URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio
- from Rev 49 to Rev 50
- ↔ Reverse comparison
Rev 49 → Rev 50
/tags/1.0.2-release/sw/stack/test_riostack.c
0,0 → 1,1955
/******************************************************************************* |
* |
* RapidIO IP Library Core |
* |
* This file is part of the RapidIO IP library project |
* http://www.opencores.org/cores/rio/ |
* |
* Description: |
* This file contains automatic regression tests for riopacket. Compile and |
* run it by using: |
* gcc -o testriostack test_riostack.c riopacket.c -fprofile-arcs -ftest-coverage |
* ./testriostack |
* gcov test_riostack.c |
* |
* To Do: |
* - |
* |
* Author(s): |
* - Magnus Rosenius, magro732@opencores.org |
* |
******************************************************************************* |
* |
* Copyright (C) 2015 Authors and OPENCORES.ORG |
* |
* This source file may be used and distributed without |
* restriction provided that this copyright statement is not |
* removed from the file and that any derivative work contains |
* the original copyright notice and the associated disclaimer. |
* |
* This source file is free software; you can redistribute it |
* and/or modify it under the terms of the GNU Lesser General |
* Public License as published by the Free Software Foundation; |
* either version 2.1 of the License, or (at your option) any |
* later version. |
* |
* This source 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 Lesser General Public License for more |
* details. |
* |
* You should have received a copy of the GNU Lesser General |
* Public License along with this source; if not, download it |
* from http://www.opencores.org/lgpl.shtml |
* |
*******************************************************************************/ |
|
#include <stdio.h> |
#include <stdlib.h> |
|
#define MODULE_TEST |
#include "riostack.c" |
|
#define PrintS(s) \ |
{ \ |
FILE *fd; \ |
fd=fopen("testspec.txt", "a"); \ |
fputs(s "\n", fd); \ |
fclose(fd); \ |
} |
|
#define TESTSTART(s) printf(s) |
#define TESTEND printf(" passed.\n"); |
|
#define TESTCOND(got) \ |
if (!(got)) \ |
{ \ |
printf("\nERROR at line %u:%s=%u (0x%08x)\n", \ |
__LINE__, #got, (got), (got)); \ |
exit(1); \ |
} |
|
#define TESTEXPR(got, expected) \ |
if ((got)!=(expected)) \ |
{ \ |
printf("\nERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", \ |
__LINE__, #got, (got), (got), (expected), (expected)); \ |
exit(1); \ |
} |
|
#define TESTSYMBOL(got, expected) testSymbol(__LINE__, #got, (got), (expected)) |
|
void testSymbol(uint32_t line, char *expression, RioSymbol_t got, RioSymbol_t expected) |
{ |
if ((got).type==(expected).type) |
{ |
switch ((got).type) |
{ |
case RIOSTACK_SYMBOL_TYPE_ERROR: |
case RIOSTACK_SYMBOL_TYPE_IDLE: |
break; |
case RIOSTACK_SYMBOL_TYPE_CONTROL: |
if((got).data != (expected).data) |
{ |
if(STYPE0_GET((got).data) != STYPE0_GET((expected).data)) |
{ |
printf("\nERROR at line %u:STYPE0=0x%02x expected=0x%02x\n", |
line, STYPE0_GET((got).data), STYPE0_GET((expected).data)); |
} |
if(PARAMETER0_GET((got).data) != PARAMETER0_GET((expected).data)) |
{ |
printf("\nERROR at line %u:PARAMETER0=0x%02x expected=0x%02x\n", |
line, PARAMETER0_GET((got).data), PARAMETER0_GET((expected).data)); |
} |
if(PARAMETER1_GET((got).data) != PARAMETER1_GET((expected).data)) |
{ |
printf("\nERROR at line %u:PARAMETER1=0x%02x expected=0x%02x\n", |
line, PARAMETER1_GET((got).data), PARAMETER1_GET((expected).data)); |
} |
if(STYPE1_GET((got).data) != STYPE1_GET((expected).data)) |
{ |
printf("\nERROR at line %u:STYPE1=0x%02x expected=0x%02x\n", |
line, STYPE1_GET((got).data), STYPE1_GET((expected).data)); |
} |
if(CMD_GET((got).data) != CMD_GET((expected).data)) |
{ |
printf("\nERROR at line %u:CMD=0x%02x expected=0x%02x\n", |
line, CMD_GET((got).data), CMD_GET((expected).data)); |
} |
if(CRC5_GET((got).data) != CRC5_GET((expected).data)) |
{ |
printf("\nERROR at line %u:CRC5=0x%02x expected=0x%02x\n", |
line, CRC5_GET((got).data), CRC5_GET((expected).data)); |
} |
exit(1); |
} |
break; |
case RIOSTACK_SYMBOL_TYPE_DATA: |
if((got).data != (expected).data) |
{ |
printf("\nERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", |
line, expression, (got).data, (got).data, (expected).data, (expected).data); |
exit(1); |
} |
break; |
} |
} |
else |
{ |
printf("\nERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", |
line, expression, (got).type, (got).type, (expected).type, (expected).type); |
exit(1); |
} |
} |
|
|
|
uint8_t createDoorbell(uint32_t *doorbell, uint8_t ackId, uint16_t destid, uint16_t srcId, uint8_t tid, uint16_t info) |
{ |
uint16_t crc; |
uint32_t content; |
|
/* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */ |
/* ackId is set when the packet is transmitted. */ |
content = 0x001aul << 16; |
content |= (uint32_t) destid; |
crc = RIOPACKET_Crc32(content, 0xffffu); |
doorbell[0] = (((uint32_t) ackId) << 27) | content; |
|
/* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */ |
content = ((uint32_t) srcId) << 16; |
content |= (uint32_t) tid; |
crc = RIOPACKET_Crc32(content, crc); |
doorbell[1] = content; |
|
/* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */ |
content = ((uint32_t) info) << 16; |
crc = RIOPACKET_Crc16(info, crc); |
content |= ((uint32_t) crc); |
doorbell[2] = content; |
|
return 3; |
|
} |
|
/******************************************************************************* |
* Module test for this file. |
*******************************************************************************/ |
int32_t main(void) |
{ |
RioStack_t stack; |
uint32_t rxPacketBuffer[RIOSTACK_BUFFER_SIZE*8], txPacketBuffer[RIOSTACK_BUFFER_SIZE*8]; |
RioPacket_t rioPacket; |
uint32_t packet[69]; |
RioSymbol_t s, c, d; |
int i, j, k; |
uint16_t length; |
uint16_t dstid; |
uint16_t srcid; |
uint8_t tid; |
uint8_t hop; |
uint8_t mailbox; |
uint16_t info; |
uint32_t address; |
uint32_t data; |
uint8_t payload8[256]; |
uint8_t payload8Expected[256]; |
uint32_t packetLength; |
|
|
/************************************************************************* |
* Test prelude. |
* Setup the RIO stack for operation. |
*************************************************************************/ |
|
/* Open the stack and set the port status to initialized. */ |
RIOSTACK_open(&stack, NULL, |
RIOSTACK_BUFFER_SIZE*8, &rxPacketBuffer[0], |
RIOSTACK_BUFFER_SIZE*8, &txPacketBuffer[0]); |
|
/* Set the port timeout. */ |
RIOSTACK_portSetTimeout(&stack, 1); |
|
/* Set the current port time. */ |
RIOSTACK_portSetTime(&stack, 0); |
|
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("TG_riostack"); |
PrintS("----------------------------------------------------------------------"); |
PrintS("TG_riostack-TC1"); |
PrintS("Description: Test link initialization and normal packet exchange."); |
PrintS("Requirement: XXXXX"); |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send packets when port is uninitialized."); |
PrintS("Result: All packets should be ignored during initialization."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step1"); |
/******************************************************************************/ |
|
/* Place a packet in the outbound queue to check that it is received once |
the transmitter is placed in the correct state. */ |
RIOPACKET_setDoorbell(&rioPacket, 1, 0xffff, 0, 0xdeaf); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Check that only idle symbols are transmitted when the port has not been |
initialied even if statuses are received. */ |
for(i = 0; i < 1024; i++) |
{ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0)); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
|
/******************************************************************************/ |
TESTEND; |
/*****************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Set port initialized and get symbols from the stack."); |
PrintS("Result: Status-control-symbols should be generated each 256 symbol."); |
PrintS("----------------------------------------------------------------------"); |
/*****************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step2"); |
/*****************************************************************************/ |
|
/* Set the port status to intialized. */ |
RIOSTACK_portSetStatus(&stack, 1); |
|
/* Set port time. */ |
RIOSTACK_portSetTime(&stack, 1); |
|
/* Check that status-control-symbols are transmitted once every 256 symbol. */ |
for(j = 0; j < 15; j++) |
{ |
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
} |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Add a status-control-symbol to the receiver."); |
PrintS("Result: Status-control-symbols should be generated each 15 symbol."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step3"); |
/*****************************************************************************/ |
|
/* Insert a status-control-symbol in the receive. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0)); |
|
/* Check that status-control-symbols are transmitted once every 16 symbol. */ |
for(i = 0; i < 15; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Add a packet to the receiver."); |
PrintS("Result: Packet should be ignored until the link is initialized."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step4"); |
/*****************************************************************************/ |
|
/* Send a packet. Note that the start and end of the packet contains a status. */ |
packetLength = createDoorbell(packet, 0, 0, 0, 0, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that packet was not received. */ |
TESTEXPR(RIOSTACK_getInboundQueueLength(&stack), 0); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Add four more status-control-symbols followed by one with error in "); |
PrintS(" CRC5. Then send a packet."); |
PrintS("Result: The receiver should remain in port initialized and packet should "); |
PrintS(" still be ignored."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step5"); |
/*****************************************************************************/ |
|
/* Send 4 more status-control-symbols followed by one erronous. */ |
for(i = 0; i < 4; i++) |
{ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0)); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0); |
c.data ^= 1; |
RIOSTACK_portAddSymbol(&stack, c); |
|
/* Send a packet. Note that the start and end of the packet contains status. */ |
packetLength = createDoorbell(packet, 0, 0, 0, 0, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet was ignored. */ |
TESTEXPR(RIOSTACK_getInboundQueueLength(&stack), 0); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 6:"); |
PrintS("Action: Add six more status-control-symbols. Then send a packet."); |
PrintS("Result: The receiver should enter link initialized and the packet should "); |
PrintS(" be received."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step6"); |
/*****************************************************************************/ |
|
/* Send 6 more status-control-symbols. */ |
for(i = 0; i < 6; i++) |
{ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 1, STYPE1_NOP, 0)); |
} |
|
/* Send a packet and check that it is accepted. */ |
/* The ackId on receiver in testobject is updated when this has been transmitted. */ |
packetLength = createDoorbell(packet, 0, 0, 0, 0, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 0, 8, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet is received. */ |
TESTEXPR(RIOSTACK_getInboundQueueLength(&stack), 1); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 7:"); |
PrintS("Action: Get symbols from transmitter."); |
PrintS("Result: Status-control-symbols should still be generated each 15 symbol "); |
PrintS("until a total of 15 status-control-symbols has been transmitted. Once these "); |
PrintS("has been transmitted, the transmitter will be link initialized."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step7"); |
/*****************************************************************************/ |
|
/* Note that the available buffers in the receiver should have decremented once |
since the previously received packet has not been read from the application |
side of the stack yet. */ |
for(j = 0; j < 14; j++) |
{ |
for(i = 0; i < 15; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
} |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 8:"); |
PrintS("Action: Get the first symbol from the transmitter once the link-intialized "); |
PrintS(" state has been entered."); |
PrintS("Result: A packet-accepted-symbol should be received for the newly received "); |
PrintS(" packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step8"); |
/*****************************************************************************/ |
|
c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 7, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 9:"); |
PrintS("Action: Get the next symbols from the transmitter."); |
PrintS("Result: The packet placed in the outbound queue at startup should be "); |
PrintS(" received. Dont acknowledge the packet yet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step9"); |
/*****************************************************************************/ |
|
/* Create a packet. */ |
packetLength = createDoorbell(packet, 0, 1, 0xffff, 0, 0xdeaf); |
|
/* Receive the start of the frame. */ |
c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Receive the data of the frame. */ |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
/* Receive the end of the frame. */ |
c = CreateControlSymbol(STYPE0_STATUS, 1, 7, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 10:"); |
PrintS("Action: Remove the packet from the inbound queue. Dont acknowledge the"); |
PrintS(" transmitted packet yet."); |
PrintS("Result: Check that status-control-symbols are sent each 256 symbol and that "); |
PrintS(" the buffer count is updated when the inbound packet has been read."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step10"); |
/*****************************************************************************/ |
|
/* Simulate the application reading the received packet to free one reception |
buffer. */ |
RIOSTACK_getInboundPacket(&stack, &rioPacket); |
|
/* Check that the status-control-symbols are generated each 256 symbol. */ |
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
|
/* Check that the buffer status has been updated. */ |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 11:"); |
PrintS("Action: Send a packet when an acknowledge has not been received."); |
PrintS("Result: Only idle and status control symbols should be transmitted until "); |
PrintS(" the packet-accepted symbol has been received."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step11"); |
/*****************************************************************************/ |
|
/* Place a packet in the outbound queue. */ |
RIOPACKET_setDoorbell(&rioPacket, 2, 0xffff, 1, 0xc0de); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
packetLength = createDoorbell(packet, 1, 2, 0xffff, 1, 0xc0de); |
|
/* Receive the start of the frame. */ |
c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Receive the data of the frame. */ |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
/* Receive the end of the frame. */ |
c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 12:"); |
PrintS("Action: Send a packet-accepted symbol."); |
PrintS("Result: Check that the new packet is transmitted."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step12"); |
/*****************************************************************************/ |
|
/* Send acknowledge for the first frame. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 0, 1, STYPE1_NOP, 0)); |
|
/* Check that status-control-symbols are transmitted once every 256 symbol with |
updated ackId. */ |
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 13:"); |
PrintS("Action: Send a packet-accepted symbol."); |
PrintS("Result: Check that only idle and status-control-symbols are transmitted "); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC1-Step13"); |
/*****************************************************************************/ |
|
/* Acknowledge the second frame. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1, 1, STYPE1_NOP, 0)); |
|
/* Check that status-control-symbols are transmitted once every 256 symbol with |
updated ackId. */ |
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 1, 8, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("TG_riostack-TC2"); |
PrintS("Description: Test flow control."); |
PrintS("Requirement: XXXXX"); |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send packets to receiver but don't acknowledge them."); |
PrintS("Result: The reception queue of the stack is full."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step1"); |
/******************************************************************************/ |
|
/* Fill input queue in receiver. */ |
for(j = 0; j < 8; j++) |
{ |
packetLength = createDoorbell(packet, 1+j, 0, 0, 1+j, 0); |
|
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0)); |
|
c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 1+j, 7-j, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
} |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Send a packet when the inbound queue of the stack is full."); |
PrintS("Result: The stack sends a packet-retry symbol. The receiver will end up in "); |
PrintS("input-retry-stopped state."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step2"); |
/******************************************************************************/ |
|
/* Send another packet. */ |
packetLength = createDoorbell(packet, 9, 0, 0, 9, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0)); |
|
/* Receive indication from stack that the packet must be retried. */ |
c = CreateControlSymbol(STYPE0_PACKET_RETRY, 9, 0, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Send a packet when the receiver is in input-retry-stopped."); |
PrintS("Result: The receiver should ignore the new packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step3"); |
/******************************************************************************/ |
|
/* Resend the packet. */ |
packetLength = createDoorbell(packet, 9, 0, 0, 9, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0)); |
s = RIOSTACK_portGetSymbol(&stack); |
|
/* Check that nothing is transmitted. */ |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
|
/* REMARK: Send other symbols here to check that they are handled as expected... */ |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Send restart-from-retry and resend the previous packet."); |
PrintS("Result: The receiver should leave the input-retry-stopped state and receive "); |
PrintS(" the new frame."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step4"); |
/******************************************************************************/ |
|
/* Send restart-from-retry. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_RESTART_FROM_RETRY, 0)); |
|
/* Check that the transaction id is correct and remove a packet from the inbound |
queue. One entry in the inbound queue will be empty. */ |
RIOSTACK_getInboundPacket(&stack, &rioPacket); |
RIOPACKET_getDoorbell(&rioPacket, &dstid, &srcid, &tid, &info); |
TESTEXPR(tid, 1); |
|
/* Check that the buffer status has changed to show that a buffer is available. */ |
s = RIOSTACK_portGetSymbol(&stack); |
while(s.type == RIOSTACK_SYMBOL_TYPE_IDLE) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Resend the packet and check that it is received. */ |
packetLength = createDoorbell(packet, 9, 0, 0, 9, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0)); |
c = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 0, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Place receiver in input-retry-stopped state."); |
PrintS("Result: Check that packets may be transmitted normally."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step5"); |
/******************************************************************************/ |
|
/* Send another packet and check that the receiver indicates that it should be retried. */ |
packetLength = createDoorbell(packet, 10, 0, 0, 10, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 2, 1, STYPE1_END_OF_PACKET, 0)); |
c = CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 0, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send two packets to see that the first acknowledge has been processed. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 2, 0xfeed); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 3, 0xdeed); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Get the first packet. */ |
packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
/* Get the second packet. */ |
packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Indicate the packets must be retransmitted. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 2, 1, STYPE1_NOP, 0)); |
|
/* Receive confirmation that the packet will be retransmitted. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
|
/* Get the retransmission of the first packet. */ |
packetLength = createDoorbell(packet, 2, 0, 0xffff, 2, 0xfeed); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
/* Get the retransmission of the second packet. */ |
packetLength = createDoorbell(packet, 3, 0, 0xffff, 3, 0xdeed); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Confirm the reception of the packets. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 2, 1, STYPE1_NOP, 0)); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 3, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 6:"); |
PrintS("Action: Send status-control-symbol to show that no packets can be "); |
PrintS(" transmitted."); |
PrintS("Result: No packets should be transmitted."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step6"); |
/******************************************************************************/ |
|
/* Send status with bufferStatus set to zero. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 0, STYPE1_NOP, 0)); |
|
/* Send a packet. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 4, 0xf00d); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Check that nothing is transmitted but status-control-symbols. */ |
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 7:"); |
PrintS("Action: Indicate free buffers and receive a frame, then request it to be "); |
PrintS("retried."); |
PrintS("Result: The packet should be retransmitted."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step7"); |
/******************************************************************************/ |
|
/* Send status with bufferStatus set to available. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 4, 1, STYPE1_NOP, 0)); |
|
/* Get the packet but request it to be retried. */ |
packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 4, 1, STYPE1_NOP, 0)); |
|
/* Check the acknowledge of the retransmission. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_RESTART_FROM_RETRY, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Get the packet and acknowledge it. */ |
packetLength = createDoorbell(packet, 4, 0, 0xffff, 4, 0xf00d); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 0, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 4, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 8:"); |
PrintS("Action: Read all inbound packets from the reception queue."); |
PrintS("Result: The buffer status should be updated."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step8"); |
/******************************************************************************/ |
|
for(j = 0; j < 8; j++) |
{ |
RIOSTACK_getInboundPacket(&stack, &rioPacket); |
RIOPACKET_getDoorbell(&rioPacket, &dstid, &srcid, &tid, &info); |
TESTEXPR(tid, j+2); |
|
for(i = 0; i < 255; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
s = RIOSTACK_portGetSymbol(&stack); |
c = CreateControlSymbol(STYPE0_STATUS, 10, j+1, STYPE1_NOP, 0); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
} |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 9:"); |
PrintS("Action: Send a restart-from-retry to make the receiver leave the "); |
PrintS(" input-retry-stopped state."); |
PrintS("Result: New packets should be received again."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC2-Step9"); |
/******************************************************************************/ |
|
/* Send restart-from-retry. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_RESTART_FROM_RETRY, 0)); |
|
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("TG_riostack-TC3"); |
PrintS("Description: Test receiver error handling."); |
PrintS("Requirement: XXXXX"); |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send invalid ack id in packet."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate an ackId error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step1"); |
/******************************************************************************/ |
|
/* Send packet with invalid ackId, same as sent previously. */ |
packetLength = createDoorbell(packet, 9, 0, 0, 10, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 1, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Send packet with invalid CRC."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a CRC error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step2"); |
/******************************************************************************/ |
|
/* Send packet with invalid crc. */ |
packetLength = createDoorbell(packet, 10, 0, 0, 10, 0); |
packet[0] ^= 0x00000001; |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Send a packet that is too short."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a packet error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step3"); |
/******************************************************************************/ |
|
/* Send packet with valid ackid and crc but too short. */ |
packetLength = createDoorbell(packet, 10, 0, 0, 10, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0)); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[0]; |
RIOSTACK_portAddSymbol(&stack, d); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = ((uint32_t) RIOPACKET_Crc32(packet[0] & 0x07ffffff, 0xffff)) << 16; |
RIOSTACK_portAddSymbol(&stack, d); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Send a packet that is too long."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a packet error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step4"); |
/******************************************************************************/ |
|
/* Send packet with too many data symbols and without a end-of-packet. */ |
packetLength = createDoorbell(packet, 10, 0, 0, 10, 0); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_START_OF_PACKET, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
for(; i < 70; i++) |
{ |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = i; |
RIOSTACK_portAddSymbol(&stack, d); |
} |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Send a data symbol without starting a packet."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a packet error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step5"); |
/******************************************************************************/ |
|
/* Send a data symbol. */ |
packetLength = createDoorbell(packet, 10, 0, 0, 10, 0); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[0]; |
RIOSTACK_portAddSymbol(&stack, d); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 31, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 6:"); |
PrintS("Action: Send end-of-packet without matching start."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a packet error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step6"); |
/******************************************************************************/ |
|
/* Send end-of-packet. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_END_OF_PACKET, 0)); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTSYMBOL(s, c); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 7:"); |
PrintS("Action: Send a symbol indicating a codec error."); |
PrintS("Result: Input-error-stopped state should be entered and link-response "); |
PrintS(" should indicate a symbol error."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC3-Step7"); |
/******************************************************************************/ |
|
/* Send error-symbol. */ |
s.type = RIOSTACK_SYMBOL_TYPE_ERROR; |
RIOSTACK_portAddSymbol(&stack, s); |
|
/* Check that the packet is not accepted with cause error in ackId. */ |
c = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 5, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send a link-request. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS)); |
|
/* Check that a link-response is returned. */ |
/* Note that the status of the input-port will be reported as ok since a |
link-request has been received. */ |
c = CreateControlSymbol(STYPE0_LINK_RESPONSE, 10, 16, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check that a status is transmitted directly after the link-response. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_NOP, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("TG_riostack-TC4"); |
PrintS("Description: Test transmitter error handling."); |
PrintS("Requirement: XXXXX"); |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send acknowledge for a frame that has not been transmitted and "); |
PrintS(" without any frame being expected."); |
PrintS("Result: The transmitter should enter output-error-stopped and send "); |
PrintS(" link-request."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step1"); |
/******************************************************************************/ |
|
/* Packet acknowledge for unsent frame. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0)); |
|
/* Check that a link-request is received as the transmitter enters |
output-error-stopped state. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send link-response with expected ackId. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 5, 16, STYPE1_NOP, 0)); |
|
/* Send a status directly afterwards. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 5, 1, STYPE1_NOP, 0)); |
|
/* Check that packets are relayed after this. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 5, 2); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
packetLength = createDoorbell(packet, 5, 0, 0xffff, 5, 2); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Send a packet and send acknowledge for a previous frame. Then send "); |
PrintS(" a link-response indicating that the packet was received (accepted "); |
PrintS(" but reply corrupted)."); |
PrintS("Result: The transmitter should enter output-error-stopped state and send "); |
PrintS(" link-request and proceed with the next packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step2"); |
/******************************************************************************/ |
|
/* Send a packet. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 6, 2); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
packetLength = createDoorbell(packet, 6, 0, 0xffff, 6, 2); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send acknowledge for another packet. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 5, 1, STYPE1_NOP, 0)); |
|
/* Check that a link-request is received as the transmitter enters |
output-error-stopped state. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send link-response with expected ackId. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0)); |
|
/* Send a status directly afterwards. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Send a packet and let the packet-accepted time out. Then send a "); |
PrintS(" link-response indicating that the packet was not received."); |
PrintS("Result: The transmitter should enter output-error-stopped state, send a"); |
PrintS(" link-request and then resend the packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step3"); |
/******************************************************************************/ |
|
/* Set the time at frame transmission. */ |
RIOSTACK_portSetTime(&stack, 2); |
|
/* Send an output packet. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 7, 2); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Receive the transmitted packet. */ |
packetLength = createDoorbell(packet, 7, 0, 0xffff, 7, 2); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Indicate that time has passed to trigger a timeout. */ |
RIOSTACK_portSetTime(&stack, 3); |
|
/* Check that a link-request is received as the transmitter enters |
output-error-stopped state. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send link-response with expected ackId. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 7, 16, STYPE1_NOP, 0)); |
|
/* Send a status directly afterwards. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 7, 1, STYPE1_NOP, 0)); |
|
/* Receive retransmitted packet. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send acknowledge for the retransmitted packet. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 7, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Send a packet and then indicate that the packet was not accepted. "); |
PrintS(" Then send a link-response indicating that the packet was not received."); |
PrintS("Result: The transmitter should enter output-error-stopped state, send a"); |
PrintS(" link-request and then resend the packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step4"); |
/******************************************************************************/ |
|
/* Send an output packet. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 8, 3); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Receive the transmitted packet. */ |
packetLength = createDoorbell(packet, 8, 0, 0xffff, 8, 3); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send packet-not-accepted indicating CRC error. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, 4, STYPE1_NOP, 0)); |
|
/* Check that a link-request is received as the transmitter enters |
output-error-stopped state. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send link-response with expected ackId. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 8, 16, STYPE1_NOP, 0)); |
|
/* Send a status directly afterwards. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 8, 1, STYPE1_NOP, 0)); |
|
/* Receive retransmitted packet. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send acknowledge for the retransmitted packet. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 8, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Send a packet-retry for an unexpected packet. Then send a"); |
PrintS(" link-response indicating the expected ackId and a normal packet."); |
PrintS("Result: The transmitter should enter output-error-stopped state, send a"); |
PrintS(" link-request and then the normal packet."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step5"); |
/******************************************************************************/ |
|
/* Send packet-retry indicating that a packet should be retransmitted. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 8, 1, STYPE1_NOP, 0)); |
|
/* Check that a link-request is received as the transmitter enters |
output-error-stopped state. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send link-response with expected ackId. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_LINK_RESPONSE, 9, 16, STYPE1_NOP, 0)); |
|
/* Send a status directly afterwards. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_STATUS, 9, 1, STYPE1_NOP, 0)); |
|
/* Send an output packet. */ |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 9, 4); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
/* Receive retransmitted packet. */ |
packetLength = createDoorbell(packet, 9, 0, 0xffff, 9, 4); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Send acknowledge for the retransmitted packet. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 9, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
PrintS("----------------------------------------------------------------------"); |
PrintS("Step 6:"); |
PrintS("Action: Fill outbound queue with packets, then check retransmission when "); |
PrintS(" packet-retry is encountered. "); |
PrintS("Result: Packets should be retried until packet-accepted is received."); |
PrintS("----------------------------------------------------------------------"); |
/******************************************************************************/ |
TESTSTART("TG_riostack-TC4-Step6"); |
/******************************************************************************/ |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 20, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 21, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 22, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 23, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 24, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 25, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 26, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) > 0); |
RIOPACKET_setDoorbell(&rioPacket, 0, 0xffff, 27, 0xbabe); |
RIOSTACK_setOutboundPacket(&stack, &rioPacket); |
|
TESTCOND(RIOSTACK_getOutboundQueueAvailable(&stack) == 0); |
|
/* Receive transmitted packet. */ |
packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
for(i = 0; i < 10; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, RIOSTACK_SYMBOL_TYPE_IDLE); |
} |
|
/* Request retransmission. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_RETRY, 10, 1, STYPE1_NOP, 0)); |
|
/* Acknowledge retransmission. */ |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_RESTART_FROM_RETRY, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
/* Check retransmitted packets. */ |
packetLength = createDoorbell(packet, 10, 0, 0xffff, 20, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 11, 0, 0xffff, 21, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 12, 0, 0xffff, 22, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
/* Acknowledge. */ |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 10, 1, STYPE1_NOP, 0)); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 11, 1, STYPE1_NOP, 0)); |
|
packetLength = createDoorbell(packet, 13, 0, 0xffff, 23, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 14, 0, 0xffff, 24, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 12, 1, STYPE1_NOP, 0)); |
|
packetLength = createDoorbell(packet, 15, 0, 0xffff, 25, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
|
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 13, 1, STYPE1_NOP, 0)); |
|
packetLength = createDoorbell(packet, 16, 0, 0xffff, 26, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 14, 1, STYPE1_NOP, 0)); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
packetLength = createDoorbell(packet, 17, 0, 0xffff, 27, 0xbabe); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_START_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
for(i = 0; i < packetLength; i++) |
{ |
s = RIOSTACK_portGetSymbol(&stack); |
d.type = RIOSTACK_SYMBOL_TYPE_DATA; |
d.data = packet[i]; |
TESTEXPR(s.type, d.type); |
TESTEXPR(s.data, d.data); |
} |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 15, 1, STYPE1_NOP, 0)); |
c = CreateControlSymbol(STYPE0_STATUS, 10, 8, STYPE1_END_OF_PACKET, 0); |
s = RIOSTACK_portGetSymbol(&stack); |
TESTEXPR(s.type, c.type); |
TESTEXPR(s.data, c.data); |
|
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 16, 1, STYPE1_NOP, 0)); |
RIOSTACK_portAddSymbol(&stack, CreateControlSymbol(STYPE0_PACKET_ACCEPTED, 17, 1, STYPE1_NOP, 0)); |
|
/******************************************************************************/ |
TESTEND; |
/******************************************************************************/ |
|
return 0; |
} |
|
/*************************** end of file **************************************/ |
/tags/1.0.2-release/sw/stack/riostack.c
0,0 → 1,2166
/******************************************************************************* |
* |
* RapidIO IP Library Core |
* |
* This file is part of the RapidIO IP library project |
* http://www.opencores.org/cores/rio/ |
* |
* Description: |
* This file contains a software implementation of a RapidIO stack according to |
* the 2.2 version, part 6, of the standard. Only short control symbols are |
* supported. |
* |
* Symbols are in four flavors, idle, control, data and error. They are abstract |
* and should be serialized by any implementation to be sent on a transmission |
* channel. Error symbols are never generated by the stack and are used if the |
* symbol decoder encounters an error that the stack should be notified of. |
* |
* Symbols are inserted into the stack from the lower-half by calling |
* RIOSTACK_portAddSymbol() and symbols to transmit are fetched from the stack |
* using RIOSTACK_portGetSymbol(). These two functions are the low-level interface |
* towards a physical transmission channel. |
* The function RIOSTACK_portSetStatus() is used to indicate to the stack that initial |
* training of the symbol codec has been completed and that the transmission port |
* is ready to accept other symbols than idle. The procedure is to set the port |
* status to initialized once idle symbols are successfully received. |
* |
* On the upper-half interface are the RIOSTACK_setOutboundPacket() function used to |
* insert packets into the outbound transmission queue and RIOSTACK_getInboundPacket() |
* is used to get packet from the inbound reception queue. The |
* RIOSTACK_getInboundQueueLength() function is used to check if any packet is available |
* for reading in the inbound reception queue. |
* |
* ----------------- |
* | OS dependent | |
* | (your code) | |
* ----------------- |
* | |
* ----------------- |
* | RioStack | |
* ----------------- |
* | |
* ----------------- |
* | Symbol Codec | |
* | (your code) | |
* ----------------- |
* | |
* ----------------- |
* | Port driver | |
* ----------------- |
* | |
* ----------------- |
* | Physical port | |
* ----------------- |
* |
* The symbol codec maps a RapidIO symbol to the physical transmission media. |
* |
* Some typical patterns to handle this stack are: |
* Initialization: |
* RIOSTACK_open(...); |
* RIOSTACK_portSetTimeout(...); |
* ... |
* <Symbol transcoder is successfully decoding symbols from the link> |
* RIOSTACK_portSetStatus(1); |
* |
* Bottom-half traffic handling: |
* RIOSTACK_portSetTime(...); |
* <get symbol from decoder> |
* RIOSTACK_portAddSymbol(...); |
* s = RIOSTACK_portGetSymbol(...); |
* <send symbol to encoder> |
* |
* Receiving packets: |
* if(RIOSTACK_getInboundQueueLength(...) > 0) |
* { |
* RIOSTACK_getInboundPacket(...); |
* <process the new packet> |
* } |
* |
* Transmitting packets: |
* <create a new packet> |
* if(RIOSTACK_getOutboundQueueAvailable(...) > 0) |
* { |
* RIOSTACK_setOutboundPacket(...); |
* } |
* |
* More details about the usage can be found in the module tests in test_riostack.c. |
* |
* To Do: |
* - Optimize the packing of stype0 and stype1 into control symbols. |
* |
* Author(s): |
* - Magnus Rosenius, magro732@opencores.org |
* |
******************************************************************************* |
* |
* Copyright (C) 2015 Authors and OPENCORES.ORG |
* |
* This source file may be used and distributed without |
* restriction provided that this copyright statement is not |
* removed from the file and that any derivative work contains |
* the original copyright notice and the associated disclaimer. |
* |
* This source file is free software; you can redistribute it |
* and/or modify it under the terms of the GNU Lesser General |
* Public License as published by the Free Software Foundation; |
* either version 2.1 of the License, or (at your option) any |
* later version. |
* |
* This source 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 Lesser General Public License for more |
* details. |
* |
* You should have received a copy of the GNU Lesser General |
* Public License along with this source; if not, download it |
* from http://www.opencores.org/lgpl.shtml |
* |
*******************************************************************************/ |
|
|
/** |
* \file riostack.c |
*/ |
|
/******************************************************************************* |
* Includes |
*******************************************************************************/ |
|
#include "riostack.h" |
|
|
/*lint -e961 Allow function like macros. */ |
/*lint -e621 Long identifier names allowed to increase readability. */ |
/*lint -w2 */ |
|
|
/*lint --estring(960,17.4) It is not possible to implement a rio stack without some |
* pointer arithmetic */ |
|
|
/******************************************************************************* |
* Local macro definitions |
*******************************************************************************/ |
|
/* Macro to update 5-bit ackId counters. */ |
#define ACKID_INC(ackId) (((ackId)+1)&0x1f) |
|
/* Macros to get entries from a control symbol. */ |
#define STYPE0_GET(data) ((uint8_t) (((data) >> 21) & 0x00000007u)) |
#define PARAMETER0_GET(data) ((uint8_t) (((data) >> 16) & 0x00000001fu)) |
#define PARAMETER1_GET(data) ((uint8_t) (((data) >> 11) & 0x00000001fu)) |
#define STYPE1_GET(data) ((uint8_t) (((data) >> 8) & 0x00000007u)) |
#define CMD_GET(data) ((uint8_t) (((data) >> 5) & 0x00000007u)) |
#define CRC5_GET(data) ((uint8_t) (((data) >> 0) & 0x0000001fu)) |
|
/* Macros to get entries from a packet in a buffer. */ |
#define FTYPE_GET(p) (((p)[0] >> 16) & 0xf) |
#define DESTID_GET(p) ((p)[0] & 0xffff) |
#define SRCID_GET(p) (((p)[1] >> 16) & 0xffff) |
#define TRANSACTION_GET(p) (((p)[1] >> 12) & 0xf) |
#define MSGLEN_GET(p) TRANSACTION_GET(p) |
#define SSIZE_GET(p) (((p)[1] >> 8) & 0xf) |
#define LETTER_GET(p) (((p)[1] >> 6) & 0x3) |
#define MBOX_GET(p) (((p)[1] >> 4) & 0x3) |
#define MSGSEG_GET(p) ((p)[1] & 0xf) |
#define XMBOX_GET(p) MSGSEG_GET(p) |
#define RDSIZE_GET(p) SSIZE_GET(p) |
#define WRSIZE_GET(p) SSIZE_GET(p) |
#define TID_GET(p) ((p)[1] & 0xff) |
#define HOP_GET(p) (((p)[2] >> 24) & 0xff) |
#define CONFIG_OFFSET_GET(p) ((p)[2] & 0x00fffffcul) |
#define INFO_GET(p) (((p)[2] >> 16) & 0xffff) |
#define ADDRESS_GET(p) ((p)[2] & 0xfffffff8ul) |
#define WDPTR_GET(p) (((p)[2] >> 2) & 0x1) |
#define XAMBS_GET(p) ((p)[2] & 0x3) |
#define DOUBLE_WORD_MSB_GET(p, i) (p)[3+(2*i+0)] |
#define DOUBLE_WORD_LSB_GET(p, i) (p)[3+(2*i+1)] |
|
/* Transmitter frame states. */ |
#define TX_FRAME_START ((uint8_t)0u) |
#define TX_FRAME_BODY ((uint8_t)1u) |
|
/* Control symbol constants. */ |
#define STYPE0_PACKET_ACCEPTED ((uint8_t)0x00u) |
#define STYPE0_PACKET_RETRY ((uint8_t)0x01u) |
#define STYPE0_PACKET_NOT_ACCEPTED ((uint8_t)0x02u) |
#define STYPE0_RESERVED ((uint8_t)0x03u) |
#define STYPE0_STATUS ((uint8_t)0x04u) |
#define STYPE0_VC_STATUS ((uint8_t)0x05u) |
#define STYPE0_LINK_RESPONSE ((uint8_t)0x06u) |
#define STYPE0_IMPLEMENTATION_DEFINED ((uint8_t)0x07u) |
#define STYPE1_START_OF_PACKET ((uint8_t)0x00u) |
#define STYPE1_STOMP ((uint8_t)0x01u) |
#define STYPE1_END_OF_PACKET ((uint8_t)0x02u) |
#define STYPE1_RESTART_FROM_RETRY ((uint8_t)0x03u) |
#define STYPE1_LINK_REQUEST ((uint8_t)0x04u) |
#define STYPE1_MULTICAST_EVENT ((uint8_t)0x05u) |
#define STYPE1_RESERVED ((uint8_t)0x06u) |
#define STYPE1_NOP ((uint8_t)0x07u) |
|
/* Packet ftype constants. */ |
#define FTYPE_REQUEST 0x2 |
#define FTYPE_WRITE 0x5 |
#define FTYPE_MAINTENANCE 0x8 |
#define FTYPE_DOORBELL 0xa |
#define FTYPE_MESSAGE 0xb |
#define FTYPE_RESPONSE 0xd |
|
/* Transaction constants. */ |
#define TRANSACTION_MAINT_READ_REQUEST 0 |
#define TRANSACTION_MAINT_WRITE_REQUEST 1 |
#define TRANSACTION_MAINT_READ_RESPONSE 2 |
#define TRANSACTION_MAINT_WRITE_RESPONSE 3 |
#define TRANSACTION_WRITE_NWRITE 4 |
#define TRANSACTION_WRITE_NWRITER 5 |
#define TRANSACTION_REQUEST_NREAD 4 |
#define TRANSACTION_RESPONSE_NO_PAYLOAD 0 |
#define TRANSACTION_RESPONSE_MESSAGE_RESPONSE 1 |
#define TRANSACTION_RESPONSE_WITH_PAYLOAD 8 |
|
/* Maintenance transaction lengths. */ |
#define MAINTENANCE_TRANSACTION_READ_REQUEST_SIZE ((uint32_t) 4ul) |
#define MAINTENANCE_TRANSACTION_WRITE_REQUEST_SIZE ((uint32_t) 6ul) |
#define MAINTENANCE_TRANSACTION_READ_RESPONSE_SIZE ((uint32_t) 6ul) |
#define MAINTENANCE_TRANSACTION_WRITE_RESPONSE_SIZE ((uint32_t) 4ul) |
|
/* Constants used to forward different errors to the link partner. */ |
#define PACKET_NOT_ACCEPTED_CAUSE_RESERVED 0u |
#define PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID 1u |
#define PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC 2u |
#define PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE 3u |
#define PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC 4u |
#define PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER 5u |
#define PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCE 6u |
#define PACKET_NOT_ACCEPTED_CAUSE_DESCRAMBLER 7u |
#define PACKET_NOT_ACCEPTED_CAUSE_GENERAL 31u |
|
/* Constants used to request link-responses. */ |
#define LINK_REQUEST_RESET_DEVICE 3u |
#define LINK_REQUEST_INPUT_STATUS 4u |
|
/* Constants used to forward a port status in a link-resonse. */ |
#define LINK_RESPONSE_PORT_STATUS_ERROR 2u |
#define LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED 4u |
#define LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED 5u |
#define LINK_RESPONSE_PORT_STATUS_OK 16u |
|
|
|
/******************************************************************************* |
* Local typedefs |
*******************************************************************************/ |
|
|
|
/******************************************************************************* |
* Global declarations |
*******************************************************************************/ |
|
|
|
/******************************************************************************* |
* Local declarations |
*******************************************************************************/ |
|
|
|
/******************************************************************************* |
* Local function prototypes |
*******************************************************************************/ |
|
/* Helper functions for protocol events. */ |
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus); |
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus); |
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus); |
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause); |
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus); |
static void handleStartOfPacket(RioStack_t *stack); |
static void handleEndOfPacket(RioStack_t *stack); |
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd); |
static void handleNewPacketStart(RioStack_t *stack); |
static void handleNewPacketEnd(RioStack_t *stack); |
|
/** |
* \brief Create a control symbol. |
* |
* \param[in] stype0 The stype0 value. |
* \param[in] parameter0 The parameter0 value. |
* \param[in] parameter1 The parameter1 value. |
* \param[in] stype1 The stype1 value. |
* \param[in] cmd The cmd value. |
* \return The control symbol that were created from the input parameters. |
* |
* This function creates a control symbol with the specified arguments and |
* calculates a CRC-5 checksum according to the standard specification. |
*/ |
static RioSymbol_t CreateControlSymbol(const uint8_t stype0, |
const uint8_t parameter0, const uint8_t parameter1, |
const uint8_t stype1, const uint8_t cmd); |
|
/** |
* \brief Function to calculate ITU-CRC5, polynom=0x15. |
* |
* \param[in] data The data of a control symbol. |
* \param[in] crc The crc to initiate the result with. |
* \return A new CRC-5 value. |
*/ |
static uint8_t Crc5(const uint32_t data, const uint8_t crc); |
|
/** |
* \brief Create a queue with a specified size and a buffer attached to it. |
* |
* \param[in] size The number of entries in the queue. |
* \param[in] buffer A pointer to the buffer to store the content in. |
* \return A queue with the specified size and where new data will be stored |
* to the specified buffer. |
*/ |
static Queue_t QueueCreate(const uint8_t size, uint32_t *buffer); |
|
/** |
* \brief Get number of available elements. |
* |
* \param[in] q The queue to operate on. |
* \return The number of free packet buffers in the queue. |
*/ |
static uint8_t QueueAvailable(const Queue_t q ); |
|
/** |
* \brief Get if the queue is empty or not. |
* |
* \param[in] q The queue to operate on. |
* \return Non-zero if the queue is empty. |
*/ |
static int QueueEmpty(const Queue_t q); |
|
/** |
* \brief Get the length of a queue. |
* |
* \param[in] q The queue to operate on. |
* \return The number of elements in the queue. |
*/ |
static uint8_t QueueLength(const Queue_t q); |
|
/** |
* \brief Add a new element to the queue. |
* |
* \param[in] q The queue to operate on. |
* \return A queue with one added element. |
*/ |
static Queue_t QueueEnqueue(Queue_t q); |
|
/** |
* \brief Remove an element from the queue. |
* |
* \param[in] q The queue to operate on. |
* \return A queue with on removed element. |
*/ |
static Queue_t QueueDequeue(Queue_t q); |
|
/** |
* \brief Check if the readout window is empty. |
* |
* \param[in] q The queue to operate on. |
* \return If the readout window is empty. |
*/ |
static int QueueWindowEmpty(const Queue_t q); |
|
/** |
* \brief Reset the window to none. |
* |
* \param[in] q The queue to operate on. |
* \return The updated Queue_t structure. |
*/ |
static Queue_t QueueWindowReset(Queue_t q); |
|
/** |
* \brief Increase the window to the next pending element. |
* |
* \param[in] q The queue to operate on. |
* \return The updated Queue_t structure. |
*/ |
static Queue_t QueueWindowNext(Queue_t q); |
|
/** |
* \brief Set actual size of the newest element. |
* |
* \param[in] q The queue to operate on. |
* \param[in] size The size to set the newest content size to. |
*/ |
static void QueueSetSize(Queue_t q, const uint32_t size); |
|
/** |
* \brief Set content at a specified index in the newest element. |
* |
* \param[in] q The queue to operate on. |
* \param[in] index posititon into the element |
* \param[in] content The content to set at the specified index in the newest queue element. |
*/ |
static void QueueSetContent(Queue_t q, const uint32_t index, const uint32_t content); |
|
/** |
* \brief Get a pointer to the buffer of the newest element. |
* |
* \param[in] q The queue to operate on. |
* \return A pointer to the content. |
*/ |
static uint32_t *QueueGetBackBuffer(Queue_t q ); |
|
/** |
* \brief Get the size of the oldest element. |
* \param[in] q The queue to operate on. |
* \return The size of the element. |
*/ |
static uint32_t QueueGetSize(Queue_t q ); |
|
/** |
* \brief Get the content of the oldest element at specified index. |
* \param[in] q The queue to operate on. |
* \param[in] index The index into the element to get the content from. |
* \return content of element at index position. |
*/ |
static uint32_t QueueGetFrontContent(Queue_t q, const uint32_t index); |
|
/** |
* \brief Get a pointer to the buffer of the oldest element. |
* |
* \param[in] q The queue to operate on. |
* \return A pointer to the content. |
*/ |
static uint32_t *QueueGetFrontBuffer(Queue_t q ); |
|
|
|
/******************************************************************************* |
* Global functions |
*******************************************************************************/ |
|
void RIOSTACK_open(RioStack_t *stack, void *private, |
const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer, |
const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer) |
{ |
/* Port time and timeout limit. */ |
stack->portTime = 0u; |
stack->portTimeout = 1000u; |
|
/* Setup the receiver. */ |
stack->rxState = RX_STATE_UNINITIALIZED; |
stack->rxCounter = 0u; |
stack->rxCrc = 0xffffu; |
stack->rxStatusReceived = 0u; |
stack->rxAckId = 0u; |
stack->rxAckIdAcked = 0u; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED; |
stack->rxQueue = QueueCreate((uint8_t) (rxPacketBufferSize/RIOSTACK_BUFFER_SIZE), rxPacketBuffer); |
|
/* Setup the transmitter. */ |
stack->txState = TX_STATE_UNINITIALIZED; |
stack->txCounter = 0u; |
stack->txStatusCounter = 0u; |
stack->txFrameState = TX_FRAME_START; |
stack->txAckId = 0u; |
stack->txAckIdWindow = 0u; |
stack->txQueue = QueueCreate((uint8_t) (txPacketBufferSize/RIOSTACK_BUFFER_SIZE), txPacketBuffer); |
|
/* Setup status counters for inbound direction. */ |
stack->statusInboundPacketComplete = 0ul; |
stack->statusInboundPacketRetry = 0ul; |
stack->statusInboundErrorControlCrc = 0ul; |
stack->statusInboundErrorPacketAckId = 0ul; |
stack->statusInboundErrorPacketCrc = 0ul; |
stack->statusInboundErrorIllegalCharacter = 0ul; |
stack->statusInboundErrorGeneral = 0ul; |
stack->statusInboundErrorPacketUnsupported = 0ul; |
|
/* Setup status counters for outbound direction. */ |
stack->statusOutboundPacketComplete = 0ul; |
stack->statusOutboundLinkLatencyMax = 0ul; |
stack->statusOutboundPacketRetry = 0ul; |
stack->statusOutboundErrorTimeout = 0ul; |
stack->statusOutboundErrorPacketAccepted = 0ul; |
stack->statusOutboundErrorPacketRetry = 0ul; |
|
/* Setup status counters for potential problems on the link-partner. */ |
stack->statusPartnerLinkRequest = 0ul; |
stack->statusPartnerErrorControlCrc = 0ul; |
stack->statusPartnerErrorPacketAckId = 0ul; |
stack->statusPartnerErrorPacketCrc = 0ul; |
stack->statusPartnerErrorIllegalCharacter = 0ul; |
stack->statusPartnerErrorGeneral = 0ul; |
|
/* Set pointer to user private data. */ |
stack->private = private; |
} |
|
|
|
/******************************************************************************************* |
* Stack status and queue access functions. |
* Note that status counters are accessed directly in the stack-structure. |
*******************************************************************************************/ |
|
int RIOSTACK_getStatus(RioStack_t *stack) |
{ |
return !(((stack->rxState == RX_STATE_UNINITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED)) && |
((stack->txState == TX_STATE_UNINITIALIZED) || (stack->txState == TX_STATE_PORT_INITIALIZED))); |
} |
|
|
|
void RIOSTACK_clearOutboundQueue(RioStack_t *stack) |
{ |
while(!QueueEmpty(stack->txQueue)) |
{ |
stack->txQueue = QueueDequeue(stack->txQueue); |
} |
} |
|
|
|
uint8_t RIOSTACK_getOutboundQueueLength(RioStack_t *stack) |
{ |
return QueueLength(stack->txQueue); |
} |
|
|
|
uint8_t RIOSTACK_getOutboundQueueAvailable(RioStack_t *stack) |
{ |
return QueueAvailable(stack->txQueue); |
} |
|
|
|
void RIOSTACK_setOutboundPacket(RioStack_t *stack, RioPacket_t *packet) |
{ |
uint32_t *src, *dst; |
uint32_t size; |
uint32_t i; |
|
|
ASSERT((QueueAvailable(stack->txQueue) > 0u), |
"Transmission queue packet overflow."); |
|
src = &packet->payload[0]; |
dst = QueueGetBackBuffer(stack->txQueue); |
size = packet->size; |
for(i = 0; i < size; i++) |
{ |
dst[i] = src[i]; |
} |
|
QueueSetSize(stack->txQueue, size); |
stack->txQueue = QueueEnqueue(stack->txQueue); |
} |
|
|
|
void RIOSTACK_clearInboundQueue(RioStack_t *stack) |
{ |
while(!QueueEmpty(stack->rxQueue)) |
{ |
stack->rxQueue = QueueDequeue(stack->rxQueue); |
} |
} |
|
|
|
uint8_t RIOSTACK_getInboundQueueLength(RioStack_t *stack) |
{ |
return QueueLength(stack->rxQueue); |
} |
|
|
|
uint8_t RIOSTACK_getInboundQueueAvailable(RioStack_t *stack) |
{ |
return QueueAvailable(stack->rxQueue); |
} |
|
|
|
void RIOSTACK_getInboundPacket(RioStack_t *stack, RioPacket_t *packet) |
{ |
uint32_t *src, *dst; |
uint32_t size; |
uint32_t i; |
|
|
ASSERT(!QueueEmpty(stack->rxQueue), "Reading from empty reception queue."); |
|
src = QueueGetFrontBuffer(stack->rxQueue); |
dst = &packet->payload[0]; |
size = QueueGetSize(stack->rxQueue); |
for(i = 0; i < size; i++) |
{ |
dst[i] = src[i]; |
} |
|
packet->size = size; |
stack->rxQueue = QueueDequeue(stack->rxQueue); |
} |
|
|
|
/******************************************************************************************* |
* Packet port functions. |
*******************************************************************************************/ |
|
void RIOSTACK_portSetTime(RioStack_t *stack, const uint32_t time) |
{ |
stack->portTime = time; |
} |
|
|
|
void RIOSTACK_portSetTimeout(RioStack_t *stack, const uint32_t time) |
{ |
stack->portTimeout = time; |
} |
|
|
|
void RIOSTACK_portSetStatus(RioStack_t *stack, const uint8_t initialized) |
{ |
/* REMARK: Clean the queues here as well??? */ |
if (initialized) |
{ |
stack->rxState = RX_STATE_PORT_INITIALIZED; |
stack->rxCounter = 0u; |
stack->rxCrc = 0xffffu; |
stack->rxStatusReceived = 0; |
stack->rxAckId = 0u; |
stack->rxAckIdAcked = 0u; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_RESERVED; |
|
stack->txState = TX_STATE_PORT_INITIALIZED; |
stack->txCounter = 0u; |
stack->txStatusCounter = 0u; |
stack->txFrameState = TX_FRAME_START; |
stack->txAckId = 0u; |
stack->txAckIdWindow = 0u; |
} |
else |
{ |
stack->rxState = RX_STATE_UNINITIALIZED; |
stack->txState = TX_STATE_UNINITIALIZED; |
} |
} |
|
|
|
void RIOSTACK_portAddSymbol(RioStack_t *stack, const RioSymbol_t s) |
{ |
uint8_t stype0; |
uint8_t parameter0; |
uint8_t parameter1; |
uint8_t stype1; |
|
|
switch(stack->rxState) |
{ |
case RX_STATE_PORT_INITIALIZED: |
/****************************************************************************** |
* PORT_INITIALIZED |
* This state is entered to initialize the link. Only status-control-symbols |
* are accepted in this state. When 7 error-free, i.e. with CRC5 correct, status |
* control symbols has been received, change state to linkInitialized. |
******************************************************************************/ |
|
/* Check the type of symbol. */ |
if(s.type == RIOSTACK_SYMBOL_TYPE_CONTROL) |
{ |
/* This is a control symbol. */ |
|
/* Check that the control symbol contains no errors. */ |
if(Crc5(s.data, 0x1fu) == (s.data & 0x1ful)) |
{ |
/* Error-free control symbol. */ |
|
/* Check if the symbol is a status symbol. */ |
stype0 = STYPE0_GET(s.data); |
if(stype0 == STYPE0_STATUS) |
{ |
/* Status symbol received. */ |
|
/* Indicate an error-free status has been received. */ |
stack->rxStatusReceived = 1; |
|
/* Check if enough status control symbols has been received. */ |
if(stack->rxCounter == 7u) |
{ |
/* Enough correct status control symbols has been received without |
errors in between. */ |
|
/* Setup the transmitter with the content of the symbol. */ |
stack->txAckId = PARAMETER0_GET(s.data); |
stack->txAckIdWindow = stack->txAckId; |
stack->txBufferStatus = PARAMETER1_GET(s.data); |
|
/* Set the transmitter in its normal operational mode. */ |
stack->rxState = RX_STATE_LINK_INITIALIZED; |
stack->rxCounter = 0u; |
} |
else |
{ |
/* Count the number of consequitive error-free status control symbols |
that has been received. */ |
stack->rxCounter++; |
} |
} |
else |
{ |
/* The received symbol is not a status symbol. */ |
/* Discard it. */ |
} |
} |
else |
{ |
/* CRC error in control symbol. */ |
/* Restart counting error-free status-control-symbols. */ |
stack->rxCounter = 0u; |
} |
} |
else |
{ |
/* Not a control symbol. */ |
/* Discard the symbol. */ |
} |
|
break; |
|
case RX_STATE_LINK_INITIALIZED: |
/****************************************************************************** |
* LINK_INITIALIZED |
* The normal state. Accept packets and forward them. |
******************************************************************************/ |
|
/* Check the type of symbol. */ |
switch(s.type) |
{ |
case RIOSTACK_SYMBOL_TYPE_CONTROL: |
/************************************************************************** |
* This is a control symbol. |
**************************************************************************/ |
|
/* Check if the CRC is correct. */ |
if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful)) |
{ |
/* The CRC is correct. */ |
|
/* Get the content of the control symbol. */ |
stype0 = STYPE0_GET(s.data); |
parameter0 = PARAMETER0_GET(s.data); |
parameter1 = PARAMETER1_GET(s.data); |
stype1 = STYPE1_GET(s.data); |
|
/********************************************************************************** |
* Check the stype0 part of the symbol. |
* Note that errors in this should trigger OUTPUT_ERROR_STOPPED. |
**********************************************************************************/ |
switch(stype0) |
{ |
case STYPE0_STATUS: |
/* A status containing the current ackId and the buffer status has been |
received. */ |
handleStatus(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_ACCEPTED: |
/* A packet has been accepted by the link partner. */ |
handlePacketAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_RETRY: |
/* The link partner wants us to initiate a restart of the received ackId. */ |
handlePacketRetry(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_NOT_ACCEPTED: |
/* The link partner indicates that a packet has been rejected. */ |
handlePacketNotAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_LINK_RESPONSE: |
/* The link partner has sent a response to a link-request. */ |
handleLinkResponse(stack, parameter0, parameter1); |
break; |
|
case STYPE0_VC_STATUS: |
case STYPE0_RESERVED: |
case STYPE0_IMPLEMENTATION_DEFINED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
|
/********************************************************************************** |
* Check the stype1 part of the symbol. |
* Note that errors in this should trigger INPUT_ERROR_STOPPED. |
**********************************************************************************/ |
switch(stype1) |
{ |
case STYPE1_START_OF_PACKET: |
/* Start of a new packet. */ |
handleStartOfPacket(stack); |
break; |
|
case STYPE1_END_OF_PACKET: |
/* Ending a packet. */ |
handleEndOfPacket(stack); |
break; |
|
case STYPE1_STOMP: |
/* Cancel the currently received frame. */ |
stack->rxCounter = 0; |
break; |
|
case STYPE1_RESTART_FROM_RETRY: |
/* Cancel the currently received frame when in this state. */ |
stack->rxCounter = 0; |
break; |
|
case STYPE1_LINK_REQUEST: |
/* A link-request has been received. */ |
handleLinkRequest(stack, CMD_GET(s.data)); |
break; |
|
case STYPE1_NOP: |
/* No operation symbol. */ |
/* Discard these. */ |
break; |
|
case STYPE1_MULTICAST_EVENT: |
case STYPE1_RESERVED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
} |
else |
{ |
/* The control symbol CRC is incorrect. */ |
/* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC; |
stack->statusInboundErrorControlCrc++; |
} |
break; |
|
case RIOSTACK_SYMBOL_TYPE_DATA: |
/************************************************************************** |
* This is a data symbol. |
**************************************************************************/ |
|
/* Check if a packet has been started and that it is not too long. */ |
if ((stack->rxCounter >= 1u) && (stack->rxCounter <= RIOPACKET_SIZE_MAX)) |
{ |
/* A packet has been started. */ |
|
/* Check if the ackId is correct on the first part of the packet. */ |
if ((stack->rxCounter > 1u) || |
((stack->rxCounter == 1u) && (((uint8_t)(s.data >> 27)) == stack->rxAckId))) |
{ |
/* The ackId is the expected one. */ |
|
/* Check if this is the first symbol of a packet. */ |
if (stack->rxCounter == 1u) |
{ |
/* This is the first symbol of the packet. */ |
/* Start to calculate the CRC of the packet. */ |
/* Note that the ackId should not be included in the CRC calculation. */ |
stack->rxCrc = RIOPACKET_Crc32(s.data & (uint32_t)0x03fffffful, 0xffffu); |
} |
else |
{ |
/* This is not the first symbol. */ |
/* Continue to calculate the CRC of the packet. */ |
stack->rxCrc = RIOPACKET_Crc32(s.data, stack->rxCrc); |
} |
|
/* Save the new data in the packet queue and update the reception counter. */ |
QueueSetContent(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul, s.data); |
stack->rxCounter++; |
} |
else |
{ |
/* The ackId is not correct. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID; |
stack->statusInboundErrorPacketAckId++; |
} |
} |
else |
{ |
/* No packet has been started or the packet is too long. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL; |
stack->statusInboundErrorGeneral++; |
} |
break; |
|
case RIOSTACK_SYMBOL_TYPE_ERROR: |
/************************************************************************** |
* The decoder has received a erronous symbol. |
**************************************************************************/ |
|
/* Idle symbol error. Place the receiver in input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER; |
stack->statusInboundErrorIllegalCharacter++; |
break; |
|
case RIOSTACK_SYMBOL_TYPE_IDLE: |
default: |
/************************************************************************** |
* Idle symbol or unsupported symbol. |
**************************************************************************/ |
|
/* Discard these for now. */ |
break; |
} |
break; |
|
case RX_STATE_INPUT_RETRY_STOPPED: |
/****************************************************************************** |
* INPUT_RETRY_STOPPED |
* This state is entered when no more buffers was available and a packet was |
* received. When in this state, all packets should be discarded until a |
* RESTART-FROM-RETRY symbol is received. See section 5.9.1.4 of the standard. |
* Note that it is only the input side of the port that are affected, not the |
* output side. Packets may still be transmitted and acknowledges should be |
* accepted. |
******************************************************************************/ |
|
/* Check the type of symbol. */ |
switch(s.type) |
{ |
case RIOSTACK_SYMBOL_TYPE_CONTROL: |
/* This is a control symbol. */ |
|
/* Check if the CRC is correct. */ |
if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful)) |
{ |
/* The CRC is correct. */ |
|
/* Get the content of the control symbol. */ |
stype0 = STYPE0_GET(s.data); |
parameter0 = PARAMETER0_GET(s.data); |
parameter1 = PARAMETER1_GET(s.data); |
stype1 = STYPE1_GET(s.data); |
|
/* Check the stype0 part of the symbol. */ |
switch(stype0) |
{ |
case STYPE0_STATUS: |
/* A status containing the current ackId and the buffer status has been |
received. */ |
handleStatus(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_ACCEPTED: |
/* A packet has been accepted by the link partner. */ |
handlePacketAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_RETRY: |
/* The link partner wants us to initiate a restart of the received ackId. */ |
handlePacketRetry(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_NOT_ACCEPTED: |
/* The link partner indicates that a packet has been rejected. */ |
handlePacketNotAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_LINK_RESPONSE: |
/* The link partner has sent a response to a link-request. */ |
handleLinkResponse(stack, parameter0, parameter1); |
break; |
|
case STYPE0_VC_STATUS: |
case STYPE0_RESERVED: |
case STYPE0_IMPLEMENTATION_DEFINED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
|
/* Check the stype1 part of the symbol. */ |
switch(stype1) |
{ |
case STYPE1_START_OF_PACKET: |
/* Starting new frames are ignored in this state. */ |
break; |
|
case STYPE1_END_OF_PACKET: |
/* Ending new frames are ignored in this state. */ |
break; |
|
case STYPE1_STOMP: |
/* Restarting frames are ignored in this state. */ |
break; |
|
case STYPE1_RESTART_FROM_RETRY: |
/* The link partner has confirmed our packet-retry-symbol. */ |
/* Go back to the normal state and reset the frame reception. */ |
stack->rxState = RX_STATE_LINK_INITIALIZED; |
stack->rxCounter = 0u; |
break; |
|
case STYPE1_LINK_REQUEST: |
/* A link-request has been received. */ |
handleLinkRequest(stack, CMD_GET(s.data)); |
stack->rxState = RX_STATE_LINK_INITIALIZED; |
break; |
|
case STYPE1_NOP: |
/* No operation symbol. */ |
/* Discard these. */ |
break; |
|
case STYPE1_MULTICAST_EVENT: |
case STYPE1_RESERVED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
} |
else |
{ |
/* The control symbol CRC is incorrect. */ |
/* Corrupted control symbol. Discard the symbol and enter the input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC; |
stack->statusInboundErrorControlCrc++; |
} |
break; |
|
case RIOSTACK_SYMBOL_TYPE_ERROR: |
/* Idle symbol error. Place the receiver in input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER; |
stack->statusInboundErrorIllegalCharacter++; |
break; |
|
case RIOSTACK_SYMBOL_TYPE_DATA: |
case RIOSTACK_SYMBOL_TYPE_IDLE: |
default: |
/* Data or idle symbol. */ |
/* Discard these in this state. */ |
break; |
} |
break; |
|
case RX_STATE_INPUT_ERROR_STOPPED: |
/****************************************************************************** |
* INPUT_ERROR_STOPPED |
* This state is entered when an error situation has occurred. When in this |
* state, all symbols should be discarded until a link-request-symbols has |
* been received. See section 5.13.2.6 in part 6 of the standard. |
* Note that it is only the input side of the port that are affected, not the |
* output side. Packets may still be transmitted and acknowledges should be |
* accepted. |
******************************************************************************/ |
|
/* Check the type of symbol. */ |
switch(s.type) |
{ |
case RIOSTACK_SYMBOL_TYPE_CONTROL: |
/* This is a control symbol. */ |
|
/* Check if the CRC is correct. */ |
if(Crc5(s.data, 0x1fu) == (s.data & (uint8_t)0x1ful)) |
{ |
/* The CRC is correct. */ |
|
/* Get the content of the control symbol. */ |
stype0 = STYPE0_GET(s.data); |
parameter0 = PARAMETER0_GET(s.data); |
parameter1 = PARAMETER1_GET(s.data); |
stype1 = STYPE1_GET(s.data); |
|
/* Check the stype0 part of the symbol. */ |
switch(stype0) |
{ |
case STYPE0_STATUS: |
/* A status containing the current ackId and the buffer status has been |
received. */ |
handleStatus(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_ACCEPTED: |
/* A packet has been accepted by the link partner. */ |
handlePacketAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_RETRY: |
/* The link partner wants us to initiate a restart of the received ackId. */ |
handlePacketRetry(stack, parameter0, parameter1); |
break; |
|
case STYPE0_PACKET_NOT_ACCEPTED: |
/* The link partner indicates that a packet has been rejected. */ |
handlePacketNotAccepted(stack, parameter0, parameter1); |
break; |
|
case STYPE0_LINK_RESPONSE: |
/* The link partner has sent a response to a link-request. */ |
handleLinkResponse(stack, parameter0, parameter1); |
break; |
|
case STYPE0_VC_STATUS: |
case STYPE0_RESERVED: |
case STYPE0_IMPLEMENTATION_DEFINED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
|
/* Check the stype1 part of the symbol. */ |
switch(stype1) |
{ |
case STYPE1_START_OF_PACKET: |
/* Starting new frames are ignored in this state. */ |
break; |
|
case STYPE1_END_OF_PACKET: |
/* Ending new frames are ignored in this state. */ |
break; |
|
case STYPE1_STOMP: |
/* Restarting frames are ignored in this state. */ |
break; |
|
case STYPE1_RESTART_FROM_RETRY: |
/* Restart-from-retry are ignored in this state. */ |
break; |
|
case STYPE1_LINK_REQUEST: |
/* This is the symbol we have been waiting for. */ |
/* Force the transmitter to send a link-response and go back into the normal |
operational state. */ |
/* The transmitter will always send a status as the first symbol after this. */ |
handleLinkRequest(stack, CMD_GET(s.data)); |
stack->rxState = RX_STATE_LINK_INITIALIZED; |
break; |
|
case STYPE1_NOP: |
/* No operation symbol. */ |
/* Discard these. */ |
break; |
|
case STYPE1_MULTICAST_EVENT: |
case STYPE1_RESERVED: |
default: |
/* Unsupported symbol received. */ |
/* Discard them. */ |
break; |
} |
} |
else |
{ |
/* The CRC is incorrect. */ |
/* Discard these in this state. */ |
} |
break; |
|
case RIOSTACK_SYMBOL_TYPE_DATA: |
case RIOSTACK_SYMBOL_TYPE_IDLE: |
case RIOSTACK_SYMBOL_TYPE_ERROR: |
default: |
/* Data, idle or error symbol. */ |
/* Discard these in this state. */ |
break; |
} |
break; |
|
case RX_STATE_UNINITIALIZED: |
default: |
/****************************************************************************** |
* Wait for the port to be initialized. |
******************************************************************************/ |
|
/* Discard all incoming symbols. */ |
break; |
} |
} |
|
|
|
RioSymbol_t RIOSTACK_portGetSymbol(RioStack_t *stack ) |
{ |
RioSymbol_t s; |
|
|
switch(stack->txState) |
{ |
case TX_STATE_PORT_INITIALIZED: |
/****************************************************************************** |
* PORT_INITIALIZED |
* This state is entered to initialize the link. Send status-control-symbols |
* once in a while until the receiver has received enough error-free status- |
* control-symbols and we have transmitted enough status-control-symbols. Once |
* an error-free status-control-symbol has been received, the statuses are |
* transmitted more frequently to decrease the time for the link to be |
* initialized. |
******************************************************************************/ |
|
/* Check if an idle symbol or a status control symbol should be sent. */ |
if(((stack->rxStatusReceived == 0) && (stack->txCounter == 255u)) || |
((stack->rxStatusReceived == 1) && (stack->txCounter >= 15u))) |
{ |
/* A control symbol should be sent. */ |
|
/* Create a new status symbol and reset the transmission counter. */ |
stack->txCounter = 0u; |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_NOP, 0u); |
|
/* Check if the receiver has received any error-free status and that we |
have sent at least 15 status control symbols. */ |
if((stack->rxStatusReceived == 1) && (stack->txStatusCounter < 15u)) |
{ |
/* Has not sent enough status control symbols. */ |
stack->txStatusCounter++; |
} |
else |
{ |
/* Has sent enough status control symbols. */ |
/* Dont do anything. */ |
} |
} |
else |
{ |
/* Idle symbol should be sent. */ |
s.type = RIOSTACK_SYMBOL_TYPE_IDLE; |
stack->txCounter++; |
} |
|
/* Check if we are ready to set the transmitter in a link initialized state. */ |
if ((stack->rxState == RX_STATE_LINK_INITIALIZED) && (stack->txStatusCounter == 15u)) |
{ |
/* Ready to go to link initialized. */ |
stack->txState = TX_STATE_LINK_INITIALIZED; |
stack->txFrameState = TX_FRAME_START; |
stack->txStatusCounter = 0u; |
} |
else |
{ |
/* Not ready to go to link initialized. */ |
/* Dont do anything. */ |
} |
|
break; |
|
case TX_STATE_LINK_INITIALIZED: |
/****************************************************************************** |
* LINK_INITIALIZED |
* The normal state. Accept packets and forward them. Send acknowledges when |
* the receiver has received complete packets. |
******************************************************************************/ |
|
/* Check if the receiver wants to acknowledge a packet. */ |
if(stack->rxAckId == stack->rxAckIdAcked) |
{ |
/* The receiver does not want to acknowledge a packet. */ |
|
/* Check if there are any outstanding packets and if it has timed out. */ |
if((stack->txAckId == stack->txAckIdWindow) || |
((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout)) |
{ |
/* There are no outstanding packets or there has been no timeout. */ |
|
/* Check if a packet is ongoing. */ |
if(stack->txFrameState == TX_FRAME_BODY) |
{ |
/* A packet transmission is ongoing. */ |
|
/* Check if the packet has been completly sent. */ |
if(stack->txCounter != QueueGetSize(stack->txQueue)) |
{ |
/* The packet has not been completly sent. */ |
|
/* Create a new data symbol to transmit. */ |
s.type = RIOSTACK_SYMBOL_TYPE_DATA; |
s.data = QueueGetFrontContent(stack->txQueue, (uint32_t)stack->txCounter); |
|
/* Check if this is the first symbol in a packet. */ |
if (stack->txCounter == 0u) |
{ |
/* Place the correct ackId in the right place. */ |
s.data |= (uint32_t)stack->txAckIdWindow << 27; |
} |
else |
{ |
/* Dont do anything. */ |
} |
|
/* Update the transmission counter. */ |
stack->txCounter++; |
|
/* A status control symbol was not sent. Update the status counter. */ |
stack->txStatusCounter++; |
} |
else |
{ |
/* The packet has been sent. */ |
|
/* Save the timeout time and update to the next ackId. */ |
stack->txFrameTimeout[stack->txAckIdWindow] = stack->portTime; |
stack->txAckIdWindow = ACKID_INC(stack->txAckIdWindow); |
stack->txQueue = QueueWindowNext(stack->txQueue); |
|
/* Check if there are more packets pending to be sent. */ |
/* Also check that there are buffer available at the receiver and that not too many |
packets are outstanding. */ |
if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) && |
(((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31)) |
{ |
/* More pending packets. */ |
/* Create a control symbol to signal that the new packet has started. */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_START_OF_PACKET, 0u); |
|
/* Restart transmission counter. */ |
stack->txCounter = 0; |
} |
else |
{ |
/* No more pending packets. */ |
/* Create a control symbol to signal that the packet has ended. */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_END_OF_PACKET, 0u); |
|
/* Go back to wait for a new frame. */ |
stack->txFrameState = TX_FRAME_START; |
} |
|
/* A status control symbol has been sent. Reset the status counter. */ |
stack->txStatusCounter = 0u; |
} |
} |
else |
{ |
/* No packet is being sent. */ |
|
/* Check if there are any pending packets to start sending. */ |
/* Also check that there are buffer available at the receiver and that not too many |
packets are outstanding. */ |
if(!QueueWindowEmpty(stack->txQueue) && (stack->txBufferStatus > 0) && |
(((stack->txAckIdWindow - stack->txAckId) & 0x1f) != 31)) |
{ |
/* There is a pending packet to send. */ |
/* Send a start-of-packet control symbol to start to send the packet. */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_START_OF_PACKET, 0u); |
stack->txFrameState = TX_FRAME_BODY; |
stack->txCounter = 0u; |
|
/* A status control symbol has been sent. Reset the status counter. */ |
stack->txStatusCounter = 0u; |
} |
else |
{ |
/* There are no pending packets to send. */ |
|
/* Check if a status control symbol must be transmitted. */ |
if(stack->txStatusCounter < 255u) |
{ |
/* Not required to send a status control symbol. */ |
|
/* Send an idle-symbol. */ |
s.type = RIOSTACK_SYMBOL_TYPE_IDLE; |
stack->txStatusCounter++; |
} |
else |
{ |
/* Must send a status control symbol. */ |
|
/* Create a status control symbol. */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_NOP, 0u); |
|
/* A status control symbol has been sent. Reset the status counter. */ |
stack->txStatusCounter = 0u; |
} |
} |
} |
} |
else |
{ |
/* There has been a timeout. */ |
/* A packet has been sent but no packet-accepted has been received. */ |
/* Send link-request-symbol (input-status). */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
|
/* Save the time when this was transmitted. */ |
stack->txFrameTimeout[stack->txAckId] = stack->portTime; |
|
/* Remember that this symbol has been transmitted. */ |
stack->txCounter = 1; |
|
/* Go into the output error stopped state. */ |
stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED; |
stack->statusOutboundErrorTimeout++; |
} |
} |
else |
{ |
/* The receiver wants us to send an acknowledgement. */ |
s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue), |
STYPE1_NOP, 0u); |
stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked); |
|
/* A status control symbol was not sent. Update the status counter. */ |
stack->txStatusCounter++; |
} |
break; |
|
case TX_STATE_SEND_PACKET_RETRY: |
/****************************************************************************** |
* SEND_PACKET_RETRY |
* This state is set by the receiver to force a packet-retry-symbol to be |
* transmitted. |
******************************************************************************/ |
|
/* Check if the receiver wants to acknowledge a packet. */ |
/* This must be done first or we will get an error for a missmatching |
ackId in the link-partner. */ |
if(stack->rxAckId == stack->rxAckIdAcked) |
{ |
/* No pending acknowledge. */ |
|
/* Send a packet-retry symbol to tell the link partner to retry the last frame. */ |
s = CreateControlSymbol(STYPE0_PACKET_RETRY, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_NOP, 0u); |
|
/* Proceed with normal transmission. */ |
stack->txState = TX_STATE_LINK_INITIALIZED; |
|
/* A status control symbol was not sent. Update the status counter. */ |
stack->txStatusCounter++; |
} |
else |
{ |
|
/* The receiver wants us to send an acknowledgement. */ |
s = CreateControlSymbol(STYPE0_PACKET_ACCEPTED, stack->rxAckIdAcked, QueueAvailable(stack->rxQueue), |
STYPE1_NOP, 0u); |
stack->rxAckIdAcked = ACKID_INC(stack->rxAckIdAcked); |
|
/* A status control symbol was not sent. Update the status counter. */ |
stack->txStatusCounter++; |
} |
break; |
|
case TX_STATE_SEND_PACKET_NOT_ACCEPTED: |
/****************************************************************************** |
* SEND_PACKET_NOT_ACCEPTED |
* This state is set by the receiver to force a packet-not-accepted-symbol to be |
* transmitted. |
******************************************************************************/ |
|
/* Send a packet-not-accepted symbol to indicate an error on the link. */ |
s = CreateControlSymbol(STYPE0_PACKET_NOT_ACCEPTED, 0, stack->rxErrorCause, |
STYPE1_NOP, 0u); |
|
/* Proceed with normal transmission. */ |
stack->txState = TX_STATE_LINK_INITIALIZED; |
|
/* A status control symbol was not sent. Update the status counter. */ |
stack->txStatusCounter++; |
break; |
|
case TX_STATE_SEND_LINK_RESPONSE: |
/****************************************************************************** |
* SEND_LINK_RESPONSE |
* This state is set by the receiver to force a link-response-symbol to be |
* transmitted. |
******************************************************************************/ |
|
/* Check the state of the receiver. */ |
/* REMARK: If a link-request gives this response and a link-request also makes the receiver |
enter the normal operational state, none of these states except the normal state will ever |
be used... */ |
if((stack->rxState == RX_STATE_LINK_INITIALIZED) || (stack->rxState == RX_STATE_PORT_INITIALIZED)) |
{ |
/* Normal state. */ |
s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_OK, |
STYPE1_NOP, 0u); |
} |
else if(stack->rxState == RX_STATE_INPUT_RETRY_STOPPED) |
{ |
/* Input-retry-stopped state. */ |
s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_RETRY_STOPPED, |
STYPE1_NOP, 0u); |
} |
else if(stack->rxState == RX_STATE_INPUT_ERROR_STOPPED) |
{ |
/* Input-error-stopped state. */ |
s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR_STOPPED, |
STYPE1_NOP, 0u); |
} |
else |
{ |
/* Not in the defined states. */ |
s = CreateControlSymbol(STYPE0_LINK_RESPONSE, stack->rxAckId, LINK_RESPONSE_PORT_STATUS_ERROR, |
STYPE1_NOP, 0u); |
} |
|
/* Proceed with normal transmission. */ |
stack->txState = TX_STATE_LINK_INITIALIZED; |
|
/* Force a status to be transmitted the next time to comply to the input-error-stopped |
state rules. */ |
stack->txStatusCounter = 255; |
break; |
|
case TX_STATE_OUTPUT_RETRY_STOPPED: |
/****************************************************************************** |
* OUTPUT_RETRY_STOPPED |
* This state is entered when the link-partner has transmitted a |
* packet-retry-symbol. The packet-retry-symbol is acknowledged by sending a |
* restart-from-retry-symbol. |
* This state follows 5.9.1.5 in part 6. |
******************************************************************************/ |
|
/* Send a restart-from-retry symbol to acknowledge. */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_RESTART_FROM_RETRY, 0u); |
|
/* Restart the current frame and proceed with normal operation. */ |
stack->txFrameState = TX_FRAME_START; |
stack->txState = TX_STATE_LINK_INITIALIZED; |
stack->txCounter = 0; |
|
/* Discard all packets that has not received a matching packet-accepted. */ |
stack->txAckIdWindow = stack->txAckId; |
stack->txQueue = QueueWindowReset(stack->txQueue); |
|
/* A status control symbol was sent. Reset the status counter. */ |
stack->txStatusCounter = 0; |
break; |
|
case TX_STATE_OUTPUT_ERROR_STOPPED: |
/****************************************************************************** |
* OUTPUT_ERROR_STOPPED |
* This state is entered when the link partner has encountered any problem |
* which is indicated by sending a packet-not-accepted symbol or if a packet |
* timeout has expired. The error condition is acknowledged by sending a |
* link-request-symbol and then wait for a link-response reply. |
* This state follows 5.13.2.7 in part 6. |
******************************************************************************/ |
|
/* Check if a link-request-symbol has been transmitted. */ |
if(stack->txCounter == 0) |
{ |
/* A link-request-symbol has not been transmitted. */ |
|
/* Send link-request-symbol (input-status). */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
|
/* Save the time when this was transmitted. */ |
stack->txFrameTimeout[stack->txAckId] = stack->portTime; |
|
/* Remember that this symbol has been transmitted. */ |
stack->txCounter = 1; |
} |
else |
{ |
/* A link-request-symbol has been transmitted. */ |
|
/* Check if the link partner reply has timed out. */ |
if((stack->portTime - stack->txFrameTimeout[stack->txAckId]) < stack->portTimeout) |
{ |
/* No timeout. */ |
|
/* A link-request-symbol has been transmitted. */ |
/* Send only idle-symbols until the link-response is received. */ |
s.type = RIOSTACK_SYMBOL_TYPE_IDLE; |
} |
else |
{ |
/* Link response timeout. */ |
|
/* Check if the link-partner has not responded for too many times. */ |
if(stack->txCounter < 5) |
{ |
/* Not too many timeouts. */ |
/* Retry and send a new link-request. */ |
|
/* Send link-request-symbol (input-status). */ |
s = CreateControlSymbol(STYPE0_STATUS, stack->rxAckId, QueueAvailable(stack->rxQueue), |
STYPE1_LINK_REQUEST, LINK_REQUEST_INPUT_STATUS); |
|
/* Save the time when this was transmitted. */ |
stack->txFrameTimeout[stack->txAckId] = stack->portTime; |
|
/* Increment the number of times we have retransmitted the link-request. */ |
stack->txCounter++; |
} |
else |
{ |
/* The link partner has not answered for too many times. */ |
/* Give up and set the state to uninitialized. */ |
stack->txState = TX_STATE_UNINITIALIZED; |
s.type = RIOSTACK_SYMBOL_TYPE_IDLE; |
ASSERT0("No link-response received, giving up."); |
} |
} |
} |
break; |
|
case TX_STATE_UNINITIALIZED: |
default: |
/****************************************************************************** |
* Wait for the port to be initialized. |
******************************************************************************/ |
|
/* Send only idle symbols. */ |
s.type = RIOSTACK_SYMBOL_TYPE_IDLE; |
break; |
} |
|
/* Return the created symbol. */ |
return s; |
} |
|
|
|
/******************************************************************************* |
* Local RapidIO stack helper functions. |
*******************************************************************************/ |
|
static void handleStatus(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus) |
{ |
/* Update the buffer status of the link partner. */ |
(void) ackId; |
stack->txBufferStatus = bufferStatus; |
} |
|
|
|
static void handlePacketAccepted(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus) |
{ |
uint32_t linkLatency; |
|
|
/* Check if an acknowledge is expected and that it is for a transmitted packet. */ |
if((stack->txAckId != stack->txAckIdWindow) && (ackId == stack->txAckId)) |
{ |
/* Acknowledge for a recently transmitted packet received. */ |
|
/* Check if the latency of this packet is larger than the largest encountered so far. */ |
linkLatency = stack->portTime - stack->txFrameTimeout[ackId]; |
if(linkLatency > stack->statusOutboundLinkLatencyMax) |
{ |
stack->statusOutboundLinkLatencyMax = linkLatency; |
} |
|
/* Remove the packet from the outbound queue and restart the transmission for |
a new packet. */ |
stack->txQueue = QueueDequeue(stack->txQueue); |
stack->txAckId = ACKID_INC(stack->txAckId); |
stack->statusOutboundPacketComplete++; |
} |
else |
{ |
/* Acknowledge for an unexpected ackId or not waiting for an acknowledge. */ |
/* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */ |
stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED; |
stack->txCounter = 0u; |
stack->statusOutboundErrorPacketAccepted++; |
} |
|
/* Update the buffer status of the link partner. */ |
stack->txBufferStatus = bufferStatus; |
} |
|
|
|
static void handlePacketRetry(RioStack_t *stack, const uint8_t ackId, const uint8_t bufferStatus) |
{ |
/* Check if the retried packet ackId is acceptable. */ |
if(ackId == stack->txAckId) |
{ |
/* The request for retry is for the current packet. */ |
/* Force the transmitter to send a RESTART-FROM-RETRY symbol. */ |
stack->txState = TX_STATE_OUTPUT_RETRY_STOPPED; |
stack->statusOutboundPacketRetry++; |
} |
else |
{ |
/* Link protocol violation. Discard the symbol and enter the output-error-stopped state. */ |
stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED; |
stack->txCounter = 0u; |
stack->statusOutboundErrorPacketRetry++; |
} |
|
/* Update the buffer status of the link partner. */ |
stack->txBufferStatus = bufferStatus; |
} |
|
|
|
static void handlePacketNotAccepted(RioStack_t *stack, const uint8_t arbitrary, const uint8_t cause) |
{ |
(void) arbitrary; |
|
/* Force the transmitter to enter output-error-stopped state. */ |
stack->txState = TX_STATE_OUTPUT_ERROR_STOPPED; |
stack->txCounter = 0u; |
|
/* Record the type of error that caused the packet to not being accepted. */ |
switch(cause) |
{ |
case PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID: |
stack->statusPartnerErrorPacketAckId++; |
break; |
case PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC: |
stack->statusPartnerErrorControlCrc++; |
break; |
case PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC: |
stack->statusPartnerErrorPacketCrc++; |
break; |
case PACKET_NOT_ACCEPTED_CAUSE_ILLEGAL_CHARACTER: |
stack->statusPartnerErrorIllegalCharacter++; |
break; |
default: |
stack->statusPartnerErrorGeneral++; |
break; |
} |
} |
|
|
|
static void handleLinkResponse(RioStack_t *stack, const uint8_t ackId, const uint8_t portStatus) |
{ |
uint8_t window; |
uint8_t windowReceived; |
|
|
(void) portStatus; |
|
/* Check if this symbols is expected. */ |
if(stack->txState == TX_STATE_OUTPUT_ERROR_STOPPED) |
{ |
/* Calculate the number of packets that has not received an acknowledge on our side and |
on the link-partner side. */ |
window = (stack->txAckIdWindow - stack->txAckId) & 0x1f; |
windowReceived = (ackId - stack->txAckId) & 0x1f; |
|
/* Check if the link-partners response is acceptable. */ |
if(windowReceived <= window) |
{ |
/* A link-response is expected. */ |
|
/* Remove entries in the queue that the link-partner has sent acknowledges for that has been lost. */ |
while(stack->txAckId != ackId) |
{ |
stack->txQueue = QueueDequeue(stack->txQueue); |
stack->txAckId = ACKID_INC(stack->txAckId); |
stack->statusOutboundPacketComplete++; |
} |
|
/* Set the transmission window to the resend packets that has not been received. */ |
stack->txQueue = QueueWindowReset(stack->txQueue); |
stack->txAckIdWindow = ackId; |
stack->txFrameState = TX_FRAME_START; |
|
/* Set the transmitter back into normal operation. */ |
stack->txState = TX_STATE_LINK_INITIALIZED; |
} |
else |
{ |
/* The link-partner response is unacceptable. */ |
/* Recovery is not possible. */ |
stack->txState = TX_STATE_UNINITIALIZED; |
ASSERT0("Unrecoverable protocol error."); |
} |
} |
else |
{ |
/* Not expecting a link-response. */ |
/* Just discard this symbol. */ |
/* REMARK: Add status counter here??? */ |
} |
} |
|
|
|
static void handleStartOfPacket(RioStack_t *stack) |
{ |
/* Check if a packet is already started. */ |
if(stack->rxCounter != 0u) |
{ |
/* Packet has already started. */ |
/* This indicates an implicit end-of-packet symbol and signals the previous packet as ready. */ |
|
/* Check the packet crc. */ |
if(stack->rxCrc == 0x0000u) |
{ |
/* The packet has a correct CRC. */ |
|
/* Check if the packet is long enough to contain a complete packet. */ |
if(stack->rxCounter > 3u) |
{ |
/* Packet long enough to process. */ |
|
/* Process the newly received packet and start a new one. */ |
handleNewPacketEnd(stack); |
handleNewPacketStart(stack); |
} |
else |
{ |
/* The packet has a valid CRC but is too short. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL; |
stack->statusInboundErrorGeneral++; |
} |
} |
else |
{ |
/* The packet has an invalid CRC. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC; |
stack->statusInboundErrorPacketCrc++; |
} |
} |
else |
{ |
/* Packet has not already started. */ |
handleNewPacketStart(stack); |
} |
} |
|
|
|
static void handleEndOfPacket(RioStack_t *stack) |
{ |
/* Check if the CRC is correct. */ |
if(stack->rxCrc == 0x0000u) |
{ |
/* The packet has a correct CRC. */ |
|
/* Check if the packet is long enough to contain a complete packet. */ |
if(stack->rxCounter > 3u) |
{ |
/* Packet long enough to process. */ |
|
/* Process the newly received packet. */ |
handleNewPacketEnd(stack); |
} |
else |
{ |
/* The packet has a valid CRC but is too short. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_GENERAL; |
stack->statusInboundErrorGeneral++; |
} |
} |
else |
{ |
/* The packet has an invalid CRC. */ |
/* Packet error. Enter input-error-stopped state. */ |
stack->txState = TX_STATE_SEND_PACKET_NOT_ACCEPTED; |
stack->rxState = RX_STATE_INPUT_ERROR_STOPPED; |
stack->rxErrorCause = PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC; |
stack->statusInboundErrorPacketCrc++; |
} |
} |
|
|
|
static void handleNewPacketStart(RioStack_t *stack) |
{ |
/* Check if there are buffers available to store the new frame. */ |
if (QueueAvailable(stack->rxQueue) > 0u) |
{ |
/* There are buffers available to accept the new packet. */ |
|
/* Update the reception counter to indicate the frame has started. */ |
stack->rxCounter = 1; |
} |
else |
{ |
/* There are no buffers available. */ |
/* Go to input retry stopped state. */ |
stack->statusInboundPacketRetry++; |
stack->txState = TX_STATE_SEND_PACKET_RETRY; |
stack->rxState = RX_STATE_INPUT_RETRY_STOPPED; |
} |
} |
|
|
|
static void handleNewPacketEnd(RioStack_t *stack) |
{ |
/* Save the size of the packet. */ |
QueueSetSize(stack->rxQueue, (uint32_t)stack->rxCounter - (uint32_t)1ul); |
|
/* Always forward the packet to the top of the stack. */ |
stack->rxQueue = QueueEnqueue(stack->rxQueue); |
|
/* Make sure the CRC is reset to an invalid value to avoid a packet |
accidentally being accepted. */ |
stack->rxCrc = 0xffff; |
|
/* Reset the reception counter. */ |
stack->rxCounter = 0u; |
|
/* Update the ackId for the receiver. */ |
stack->rxAckId = ACKID_INC(stack->rxAckId); |
|
/* Update status counter. */ |
stack->statusInboundPacketComplete++; |
} |
|
|
|
static void handleLinkRequest(RioStack_t *stack, uint8_t cmd) |
{ |
/* Check the command of the link-request. */ |
if(cmd == LINK_REQUEST_INPUT_STATUS) |
{ |
/* Input-status requested. */ |
/* Return input port status. */ |
|
/* Force the transmitter to send a link-response-symbol. */ |
stack->txState = TX_STATE_SEND_LINK_RESPONSE; |
} |
else if(cmd == LINK_REQUEST_RESET_DEVICE) |
{ |
/* Reset-device requested. */ |
/* REMARK: Support this??? */ |
} |
else |
{ |
/* Unrecognized command. */ |
/* Dont do anything. */ |
} |
|
/* Always cancel an ongoing frame when a link-request has been received. */ |
stack->rxCounter = 0; |
|
/* Receiving this indicates the link partner having encountered a potential problem. */ |
/* Count the number of times this happens. */ |
stack->statusPartnerLinkRequest++; |
} |
|
|
|
static RioSymbol_t CreateControlSymbol(const uint8_t stype0, |
const uint8_t parameter0, const uint8_t parameter1, |
const uint8_t stype1, const uint8_t cmd) |
{ |
RioSymbol_t s; |
|
s.type = RIOSTACK_SYMBOL_TYPE_CONTROL; |
|
s.data = ((uint32_t)stype0 & (uint32_t)0x07ul) << 21; |
s.data |= ((uint32_t)parameter0 & (uint32_t)0x1ful) << 16; |
s.data |= ((uint32_t)parameter1 & (uint32_t)0x1ful) << 11; |
s.data |= ((uint32_t)stype1 & (uint32_t)0x07ul) << 8; |
s.data |= ((uint32_t)cmd & (uint32_t)0x7ul) << 5; |
s.data |= Crc5(s.data, 0x1fu); |
|
return s; |
} |
|
|
|
static uint8_t Crc5(const uint32_t data, const uint8_t crc) |
{ |
static const uint8_t crcTable[] = { |
0x00u, 0x15u, 0x1fu, 0x0au, 0x0bu, 0x1eu, 0x14u, 0x01u, |
0x16u, 0x03u, 0x09u, 0x1cu, 0x1du, 0x08u, 0x02u, 0x17u, |
0x19u, 0x0cu, 0x06u, 0x13u, 0x12u, 0x07u, 0x0du, 0x18u, |
0x0fu, 0x1au, 0x10u, 0x05u, 0x04u, 0x11u, 0x1bu, 0x0eu |
}; |
|
uint8_t result; |
uint8_t index; |
|
result = crc; |
index = (uint8_t)((data >> 19) & (uint32_t)0x1ful) ^ result; |
result = crcTable[index]; |
index = (uint8_t)((data >> 14) & (uint32_t)0x1ful) ^ result; |
result = crcTable[index]; |
index = (uint8_t)((data >> 9) & (uint32_t)0x1ful) ^ result; |
result = crcTable[index]; |
index = (uint8_t)((data >> 4) & (uint32_t)0x1eul) ^ result; |
result = crcTable[index]; |
|
return result; |
} |
|
|
/******************************************************************************************* |
* Internal queue functions. |
*******************************************************************************************/ |
|
static Queue_t QueueCreate(const uint8_t size, uint32_t *buffer) |
{ |
Queue_t q; |
|
q.size = size; |
q.available = size; |
q.windowSize = 0u; |
q.windowIndex = 0u; |
q.frontIndex = 0u; |
q.backIndex = 0u; |
q.buffer_p = buffer; |
|
return q; |
} |
|
|
|
static uint8_t QueueAvailable(const Queue_t q) |
{ |
return q.available; |
} |
|
|
|
static int QueueEmpty(const Queue_t q) |
{ |
return (q.available == q.size); |
} |
|
|
|
static uint8_t QueueLength(const Queue_t q) |
{ |
return q.size - q.available; |
} |
|
|
|
static Queue_t QueueEnqueue(Queue_t q) |
{ |
q.backIndex++; |
if(q.backIndex == q.size) |
{ |
q.backIndex = 0; |
} |
q.available--; |
return q; |
} |
|
|
|
static Queue_t QueueDequeue(Queue_t q) |
{ |
q.frontIndex++; |
if(q.frontIndex == q.size) |
{ |
q.frontIndex = 0; |
} |
q.available++; |
if(q.windowSize == 0) |
{ |
q.windowIndex = q.frontIndex; |
} |
else |
{ |
q.windowSize--; |
} |
return q; |
} |
|
|
|
static int QueueWindowEmpty(const Queue_t q) |
{ |
return ((q.available + q.windowSize) == q.size); |
} |
|
|
|
static Queue_t QueueWindowReset(Queue_t q) |
{ |
q.windowIndex = q.frontIndex; |
q.windowSize = 0; |
return q; |
} |
|
|
|
static Queue_t QueueWindowNext(Queue_t q) |
{ |
q.windowIndex++; |
if(q.windowIndex == q.size) |
{ |
q.windowIndex = 0; |
} |
q.windowSize++; |
return q; |
} |
|
|
|
static void QueueSetSize(Queue_t q, const uint32_t size) |
{ |
(q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[0] = size; |
} |
|
|
|
static void QueueSetContent(Queue_t q, const uint32_t index, const uint32_t content) |
{ |
(q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[index+1ul] = content; |
} |
|
|
|
static uint32_t QueueGetSize(Queue_t q) |
{ |
return (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[0]; |
} |
|
|
|
static uint32_t QueueGetFrontContent(const Queue_t q, const uint32_t index) |
{ |
return (q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[index+1ul]; |
} |
|
|
|
static uint32_t *QueueGetFrontBuffer(const Queue_t q ) |
{ |
return &((q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.windowIndex))[1]); |
} |
|
|
|
static uint32_t *QueueGetBackBuffer(const Queue_t q ) |
{ |
return &((q.buffer_p+(RIOSTACK_BUFFER_SIZE*q.backIndex))[1]); |
} |
|
/*************************** end of file **************************************/ |
tags/1.0.2-release/sw/stack/riostack.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/sw/stack/test_riopacket.c
===================================================================
--- tags/1.0.2-release/sw/stack/test_riopacket.c (nonexistent)
+++ tags/1.0.2-release/sw/stack/test_riopacket.c (revision 50)
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains automatic regression tests for riopacket. Compile and
+ * run it by using:
+ * gcc -o testriopacket test_riopacket.c -fprofile-arcs -ftest-coverage
+ * ./testriopacket
+ * gcov test_riopacket.c
+ *
+ * To Do:
+ * -
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************
+ *
+ * Copyright (C) 2015 Authors and OPENCORES.ORG
+ *
+ * This source file may be used and distributed without
+ * restriction provided that this copyright statement is not
+ * removed from the file and that any derivative work contains
+ * the original copyright notice and the associated disclaimer.
+ *
+ * This source file is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This source 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this source; if not, download it
+ * from http://www.opencores.org/lgpl.shtml
+ *
+ *******************************************************************************/
+
+#include
+#include
+
+#define MODULE_TEST
+#include "riopacket.c"
+
+#define PrintS(s) \
+ { \
+ FILE *fd; \
+ fd=fopen("testspec.txt", "a"); \
+ fputs(s "\n", fd); \
+ fclose(fd); \
+ }
+
+#define TESTSTART(s) printf(s)
+#define TESTEND printf(" passed.\n");
+
+#define TESTCOND(got) \
+ if (!(got)) \
+ { \
+ printf("\nERROR at line %u:%s=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got)); \
+ exit(1); \
+ }
+
+#define TESTEXPR(got, expected) \
+ if ((got)!=(expected)) \
+ { \
+ printf("\nERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got), (expected), (expected)); \
+ exit(1); \
+ }
+
+#define TESTPACKET(got, expected) testSymbol(__LINE__, #got, (got), (expected))
+
+void testPacket(uint32_t line, char *expression, RioPacket_t got, RioPacket_t expected)
+{
+ int i;
+
+
+ if ((got).size==(expected).size)
+ {
+ for(i = 0; i < got.size; i++)
+ {
+ if(got.payload[i] != expected.payload[i])
+ {
+ printf("\nERROR at line %u:%s:payload[%u]:=%u (0x%08x) expected=%u (0x%08x)\n",
+ line, expression, i, (got).payload[i], (got).payload[i], (expected).payload[i], (expected).payload[i]);
+ exit(1);
+ }
+ }
+ }
+ else
+ {
+ printf("\nERROR at line %u:%s:size=%u (0x%08x) expected=%u (0x%08x)\n",
+ line, expression, (got).size, (got).size, (expected).size, (expected).size);
+ exit(1);
+ }
+}
+
+void packetClear(RioPacket_t *packet)
+{
+ uint32_t i;
+
+ for(i = 0; i < RIOPACKET_SIZE_MAX; i++)
+ {
+ packet->payload[i] = 0xdeadbeef;
+ }
+}
+
+/*******************************************************************************
+ * Module test for this file.
+ *******************************************************************************/
+int32_t main(void)
+{
+ RioPacket_t packet;
+ int i, j, k;
+ uint16_t length;
+ uint16_t dstidExpected, dstid;
+ uint16_t srcidExpected, srcid;
+ uint8_t tidExpected, tid;
+ uint8_t hopExpected, hop;
+ uint8_t mailboxExpected, mailbox;
+ uint16_t infoExpected, info;
+ uint32_t addressExpected, address;
+ uint32_t dataExpected, data;
+
+ uint16_t payloadSizeExpected, payloadSize;
+ uint8_t payloadExpected[256], payload[256];
+
+ uint8_t buffer[512];
+ uint16_t bufferSize;
+
+ srand(0);
+
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riopacket-TC1");
+ PrintS("Description: Test packet initialization, validation and appending.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: ");
+ PrintS("Result: ");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC1-Step1");
+ /******************************************************************************/
+
+ RIOPACKET_init(&packet);
+
+ TESTEXPR(RIOPACKET_size(&packet), 0);
+ TESTCOND(!RIOPACKET_valid(&packet));
+
+ RIOPACKET_append(&packet, 0x001a0001);
+
+ TESTEXPR(RIOPACKET_size(&packet), 1);
+ TESTCOND(!RIOPACKET_valid(&packet));
+
+ RIOPACKET_append(&packet, 0xffff0000);
+
+ TESTEXPR(RIOPACKET_size(&packet), 2);
+ TESTCOND(!RIOPACKET_valid(&packet));
+
+ RIOPACKET_append(&packet, 0xdeaf9903);
+
+ TESTEXPR(RIOPACKET_size(&packet), 3);
+ TESTCOND(RIOPACKET_valid(&packet));
+
+ /* Check that altering the ackid does not affect the validity of the packet. */
+ packet.payload[0] |= 0xfc000000;
+ TESTCOND(RIOPACKET_valid(&packet));
+
+ /* Access the packet and check its content. */
+ TESTEXPR(RIOPACKET_getFtype(&packet), RIOPACKET_FTYPE_DOORBELL);
+ TESTEXPR(RIOPACKET_getDestination(&packet), 0x0001);
+ TESTEXPR(RIOPACKET_getSource(&packet), 0xffff);
+ TESTEXPR(RIOPACKET_getTid(&packet), 0x00);
+ RIOPACKET_getDoorbell(&packet, &dstid, &srcid, &tid, &info);
+ TESTEXPR(dstid, 0x0001);
+ TESTEXPR(srcid, 0xffff);
+ TESTEXPR(tid, 0x00);
+ TESTEXPR(info, 0xdeaf);
+
+ bufferSize = RIOPACKET_serialize(&packet, sizeof(buffer), buffer);
+ TESTEXPR(bufferSize, 13);
+ TESTEXPR(buffer[0], 0x03);
+ TESTEXPR(buffer[1], 0xfc);
+ TESTEXPR(buffer[2], 0x1a);
+ TESTEXPR(buffer[3], 0x00);
+ TESTEXPR(buffer[4], 0x01);
+ TESTEXPR(buffer[5], 0xff);
+ TESTEXPR(buffer[6], 0xff);
+ TESTEXPR(buffer[7], 0x00);
+ TESTEXPR(buffer[8], 0x00);
+ TESTEXPR(buffer[9], 0xde);
+ TESTEXPR(buffer[10], 0xaf);
+ TESTEXPR(buffer[11], 0x99);
+ TESTEXPR(buffer[12], 0x03);
+
+ RIOPACKET_init(&packet);
+ RIOPACKET_deserialize(&packet, bufferSize, buffer);
+ TESTCOND(RIOPACKET_valid(&packet));
+ TESTEXPR(RIOPACKET_getFtype(&packet), RIOPACKET_FTYPE_DOORBELL);
+ TESTEXPR(RIOPACKET_getDestination(&packet), 0x0001);
+ TESTEXPR(RIOPACKET_getSource(&packet), 0xffff);
+ TESTEXPR(RIOPACKET_getTid(&packet), 0x00);
+ RIOPACKET_getDoorbell(&packet, &dstid, &srcid, &tid, &info);
+ TESTEXPR(dstid, 0x0001);
+ TESTEXPR(srcid, 0xffff);
+ TESTEXPR(tid, 0x00);
+ TESTEXPR(info, 0xdeaf);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riopacket-TC2");
+ PrintS("Description: Test maintenance packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: ");
+ PrintS("Result: ");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC2-Step1");
+ /******************************************************************************/
+
+ RIOPACKET_init(&packet);
+ RIOPACKET_setMaintReadRequest(&packet, 0xc0de, 0xbabe, 0x13, 0x41, 0xffffffff);
+ RIOPACKET_getMaintReadRequest(&packet, &dstid, &srcid, &hop, &tid, &address);
+
+ TESTCOND(RIOPACKET_valid(&packet));
+ TESTEXPR(dstid, 0xc0de);
+ TESTEXPR(srcid, 0xbabe);
+ TESTEXPR(hop, 0x13);
+ TESTEXPR(tid, 0x41);
+ TESTEXPR(address, 0x00fffffc);
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riopacket-TC3");
+ PrintS("Description: Test input/output packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: ");
+ PrintS("Result: ");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC3-Step1");
+ /******************************************************************************/
+
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("TG_riopacket-TC4");
+ PrintS("Description: Test message passing packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send a message with invalid payload length.");
+ PrintS("Result: No packet should be generated.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step1");
+ /******************************************************************************/
+
+ RIOPACKET_setMessage(&packet, 0xdead, 0xbeef, 0xc0, 0, &payloadExpected[0]);
+
+ TESTEXPR(packet.size, 0);
+ TESTCOND(!RIOPACKET_valid(&packet));
+
+ RIOPACKET_setMessage(&packet, 0xdead, 0xbeef, 0xc0, 257, &payloadExpected[0]);
+
+ TESTEXPR(packet.size, 0);
+ TESTCOND(!RIOPACKET_valid(&packet));
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+ PrintS("----------------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Test sending all possible payload sizes on random deviceIds ");
+ PrintS(" and mailboxes.");
+ PrintS("Result: The content of the packet should be equal to what was entered.");
+ PrintS("----------------------------------------------------------------------");
+ /******************************************************************************/
+ TESTSTART("TG_riostack-TC4-Step2");
+ /******************************************************************************/
+
+ for(i = 1; i <= 256; i++)
+ {
+ dstidExpected = rand();
+ srcidExpected = rand();
+ mailboxExpected = rand();
+
+ if((i%8) == 0)
+ {
+ payloadSizeExpected = 8*(i/8);
+ }
+ else
+ {
+ payloadSizeExpected = 8*(i/8+1);
+ }
+
+ for(j = 0; j < i; j++)
+ {
+ payloadExpected[j] = rand();
+ }
+
+ RIOPACKET_setMessage(&packet, dstidExpected, srcidExpected, mailboxExpected,
+ i, &payloadExpected[0]);
+ TESTCOND(RIOPACKET_valid(&packet));
+
+ RIOPACKET_getMessage(&packet, &dstid, &srcid, &mailbox, &payloadSize, &(payload[0]));
+ TESTEXPR(dstid, dstidExpected);
+ TESTEXPR(srcid, srcidExpected);
+ TESTEXPR(mailbox, mailboxExpected);
+ TESTEXPR(payloadSize, payloadSizeExpected);
+ for(j = 0; j < i; j++)
+ {
+ TESTEXPR(payload[j], payloadExpected[j]);
+ }
+ }
+
+ /******************************************************************************/
+ TESTEND;
+ /******************************************************************************/
+
+ return 0;
+}
+
+/*************************** end of file **************************************/
Index: tags/1.0.2-release/sw/stack/riopacket.c
===================================================================
--- tags/1.0.2-release/sw/stack/riopacket.c (nonexistent)
+++ tags/1.0.2-release/sw/stack/riopacket.c (revision 50)
@@ -0,0 +1,3123 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains an "object" that can create and parse RapidIO packets.
+ * It is used in the SW RapidIO stack, riostack.c, but can also be used
+ * stand-alone together with other software, for example to tunnel RapidIO
+ * packet over an arbitrary network.
+ * More details about the usage can be found in the module tests in
+ * test_riopacket.c.
+ *
+ * To Do:
+ * - Add packet handlers for 8-bit deviceIds.
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************
+ *
+ * Copyright (C) 2015 Authors and OPENCORES.ORG
+ *
+ * This source file may be used and distributed without
+ * restriction provided that this copyright statement is not
+ * removed from the file and that any derivative work contains
+ * the original copyright notice and the associated disclaimer.
+ *
+ * This source file is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This source 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this source; if not, download it
+ * from http://www.opencores.org/lgpl.shtml
+ *
+ *******************************************************************************/
+
+/**
+ * \file riopacket.c
+ */
+
+/*******************************************************************************
+ * Includes
+ *******************************************************************************/
+
+#include "riopacket.h"
+
+/* Let lint report errors and warnings only. */
+/*lint -w2 */
+
+
+/*******************************************************************************
+ * Local macro definitions
+ *******************************************************************************/
+
+/* Macros to get entries from a packet in a buffer. */
+#define FTYPE_GET(p) (((p)[0] >> 16) & 0xf)
+#define DESTID_GET(p) ((p)[0] & 0xffff)
+#define SRCID_GET(p) (((p)[1] >> 16) & 0xffff)
+#define TRANSACTION_GET(p) (((p)[1] >> 12) & 0xf)
+#define MSGLEN_GET(p) TRANSACTION_GET(p)
+#define SSIZE_GET(p) (((p)[1] >> 8) & 0xf)
+#define LETTER_GET(p) (((p)[1] >> 6) & 0x3)
+#define MBOX_GET(p) (((p)[1] >> 4) & 0x3)
+#define MSGSEG_GET(p) ((p)[1] & 0xf)
+#define XMBOX_GET(p) MSGSEG_GET(p)
+#define RDSIZE_GET(p) SSIZE_GET(p)
+#define WRSIZE_GET(p) SSIZE_GET(p)
+#define STATUS_GET(p) SSIZE_GET(p)
+#define TID_GET(p) ((p)[1] & 0xff)
+#define HOP_GET(p) (((p)[2] >> 24) & 0xff)
+#define CONFIG_OFFSET_GET(p) ((p)[2] & 0x00fffffcul)
+#define INFO_GET(p) (((p)[2] >> 16) & 0xffff)
+#define ADDRESS_GET(p) ((p)[2] & 0xfffffff8ul)
+#define WDPTR_GET(p) (((p)[2] >> 2) & 0x1)
+#define XAMBS_GET(p) ((p)[2] & 0x3)
+#define DOUBLE_WORD_MSB_GET(p, i) (p)[3+(2*i+0)]
+#define DOUBLE_WORD_LSB_GET(p, i) (p)[3+(2*i+1)]
+
+
+
+/*******************************************************************************
+ * Local function prototypes
+ *******************************************************************************/
+
+/* Functions to help get and set payload in the packets. */
+static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset,
+ const uint16_t dataOffset,
+ const uint16_t dataSize, uint8_t *data);
+static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset,
+ const uint16_t dataOffset,
+ const uint16_t dataSize, const uint8_t *data);
+
+/* Functions to help in conversions between rdsize/wrsize and size/offset. */
+static uint16_t rdsizeGet(const uint32_t address, const uint16_t size);
+static uint16_t wrsizeGet(const uint32_t address, const uint16_t size);
+static void rdsizeToOffset(uint8_t wrsize, uint8_t wdptr,
+ uint8_t *offset, uint16_t *size);
+static void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr,
+ uint8_t *offset, uint16_t *size);
+
+
+
+/*******************************************************************************
+ * Global function prototypes
+ *******************************************************************************/
+
+/**
+ * \brief Initialize a packet to an empty packet.
+ *
+ * \param[in] packet The packet to operate on.
+ *
+ * This function sets the size of a packet to zero.
+ *
+ * \note Any previous content is NOT purged.
+ */
+void RIOPACKET_init(RioPacket_t *packet)
+{
+ packet->size = 0;
+}
+
+
+/**
+ * \brief Return the size of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The size of the packet.
+ *
+ * This function gets the size of a packet in words (32-bit).
+ */
+uint8_t RIOPACKET_size(RioPacket_t *packet)
+{
+ return packet->size;
+}
+
+
+/**
+ * \brief Append data to a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] word The word to append.
+ *
+ * This function appends a specificed word (32-bit) to the end of a packet.
+ */
+void RIOPACKET_append(RioPacket_t *packet, uint32_t word)
+{
+ if(packet->size < RIOPACKET_SIZE_MAX)
+ {
+ packet->payload[packet->size] = word;
+ packet->size++;
+ }
+}
+
+
+/**
+ * \brief Check if a packet is a valid RapidIO packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The return value is zero if not ok, non-zero otherwise.
+ *
+ * This function checks if a packet has a correct length and a correct CRC.
+ * Both the embedded crc and the trailing crc are checked.
+ */
+int RIOPACKET_valid(RioPacket_t *packet)
+{
+ int returnValue;
+ uint32_t i;
+ uint16_t crc;
+
+
+ /* Check that the size of the packet is ok. */
+ if((packet->size >= RIOPACKET_SIZE_MIN) &&
+ (packet->size <= RIOPACKET_SIZE_MAX))
+ {
+ /* The packet has a valid length. */
+
+ /* Calculate CRC on the first word and disregard the ackId. */
+ crc = RIOPACKET_Crc32(packet->payload[0] & 0x03fffffful, 0xffffu);
+
+ /* Check if the packet contains an embedded crc. */
+ if(packet->size < 20)
+ {
+ /* The packet contains only one trailing crc. */
+ for(i = 1; i < packet->size; i++)
+ {
+ crc = RIOPACKET_Crc32(packet->payload[i], crc);
+ }
+ returnValue = (crc == 0x0000u);
+ }
+ else
+ {
+ /* The packet contains both a trailing and an embedded crc. */
+
+ /* Read payload to the embedded crc. Include the embedded crc in
+ the crc calculation.*/
+ for(i = 1; i < 20; i++)
+ {
+ crc = RIOPACKET_Crc32(packet->payload[i], crc);
+ }
+
+ /* Check the embedded crc. */
+ if(crc != ((uint16_t) (packet->payload[i] >> 16)))
+ {
+ /* The embedded crc is not ok. */
+ returnValue = 0;
+ }
+ else
+ {
+ /* Read the rest of the payload including the trailing crc. */
+ for(i = 20; i < packet->size; i++)
+ {
+ crc = RIOPACKET_Crc32(packet->payload[i], crc);
+ }
+ returnValue = (crc == 0x0000u);
+ }
+ }
+ }
+ else
+ {
+ /* The packet does not have a valid length. */
+ returnValue = 0;
+ }
+
+ return returnValue;
+}
+
+
+/**
+ * \brief Convert (serializes) a packet into an array of bytes.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] size The size of the buffer to write to.
+ * \param[out] buffer The address to write the result to.
+ * \return The number of bytes that were written. The value 0 will be returned if the
+ * serialized buffer does not fit into the provided buffer.
+ *
+ * This function serializes a packet into an array of bytes that can be transfered on
+ * a transmission channel.
+ */
+int RIOPACKET_serialize(RioPacket_t *packet, const uint16_t size, uint8_t *buffer)
+{
+ int returnValue;
+ int i;
+
+
+ /* Check if the packet fits into the provided buffer. */
+ if(size >= ((4*packet->size)+1))
+ {
+ /* The packet fits. */
+
+ /* Write the size of the packet and the packet content itself to the buffer. */
+ buffer[0] = packet->size;
+ for(i = 0; i < packet->size; i++)
+ {
+ buffer[(4*i)+1] = (packet->payload[i] >> 24) & 0xff;
+ buffer[(4*i)+2] = (packet->payload[i] >> 16) & 0xff;
+ buffer[(4*i)+3] = (packet->payload[i] >> 8) & 0xff;
+ buffer[(4*i)+4] = (packet->payload[i] >> 0) & 0xff;
+ }
+
+ /* Write the number of bytes that were written. */
+ returnValue = (4*packet->size)+1;
+ }
+ else
+ {
+ /* The packet does not fit into the provided buffer. */
+ returnValue = 0;
+ }
+
+ return returnValue;
+}
+
+
+/**
+ * \brief Convert (deserializes) an array of bytes to a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] size The size of the buffer to read from.
+ * \param[in] buffer The address to read from.
+ * \return The number of words contained in the resulting packet. The value 0 is
+ * returned if the deserialization was unsuccessfull.
+ *
+ * This function deserializes a packet from a byte array that was previously created
+ * by RIOPACKET_serialize().
+ *
+ * \note It is recommended to use RIOPACKET_valid() to verify the integrity of the packet
+ * once it has been deserialized.
+ */
+int RIOPACKET_deserialize(RioPacket_t *packet, const uint16_t size, const uint8_t *buffer)
+{
+ int i;
+ uint32_t temp = 0;
+
+
+ /* Check if the buffer contains a valid packet length. */
+ if(((buffer[0] >= RIOPACKET_SIZE_MIN) &&
+ (buffer[0] <= RIOPACKET_SIZE_MAX)) &&
+ ((4*buffer[0]+1) <= size))
+ {
+ /* The buffer contains a valid packet length. */
+
+ /* Read the size of the packet and the packet content itself from the buffer. */
+ packet->size = buffer[0];
+ for(i = 0; (i < 4*packet->size); i++)
+ {
+ temp <<= 8;
+ temp |= buffer[i+1];
+ if((i%4) == 3)
+ {
+ packet->payload[i/4] = temp;
+ }
+ }
+ }
+ else
+ {
+ /* The buffer does not contain a valid packet length. */
+ packet->size = 0;
+ }
+
+ return packet->size;
+}
+
+
+/**
+ * \brief Convert a packet into a printable buffer.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] buffer The address to write the string to.
+ *
+ * This function converts a packet into a human readable '\0'-terminated ASCII-format and
+ * write it to the argument buffer.
+ *
+ * \note The caller must guarantee that the destination buffer is large enough to contain
+ * the resulting string.
+ */
+#ifdef ENABLE_TOSTRING
+#include
+void RIOPACKET_toString(RioPacket_t *packet, char *buffer)
+{
+ uint8_t ftype;
+ uint8_t transaction;
+ uint16_t destId;
+ uint16_t srcId;
+ uint8_t tid;
+
+
+ ftype = RIOPACKET_getFtype(packet);
+ transaction = RIOPACKET_getTransaction(packet);
+
+ /* Check the message type and switch on it. */
+ switch(ftype)
+ {
+ case RIOPACKET_FTYPE_REQUEST:
+ /**************************************************************************************
+ * A REQUEST has been received.
+ **************************************************************************************/
+ {
+ uint32_t address;
+ uint16_t payloadSize;
+
+
+ if(transaction == RIOPACKET_TRANSACTION_REQUEST_NREAD)
+ {
+ RIOPACKET_getNread(packet, &destId, &srcId, &tid, &address, &payloadSize);
+ sprintf(buffer,
+ "NREAD: dstid=%04x srcid=%04x tid=%02x address=%08x payloadSize=%04x",
+ destId, srcId, tid, address, payloadSize);
+ }
+ else
+ {
+ sprintf(buffer, "UNKNOWN:ftype=%02x transaction=%02x", ftype, transaction);
+ }
+ }
+ break;
+
+ case RIOPACKET_FTYPE_WRITE:
+ /**************************************************************************************
+ * An WRITE has been received.
+ **************************************************************************************/
+ {
+ uint32_t address;
+ uint16_t payloadSize;
+ uint8_t payload[256];
+ uint32_t index;
+ uint32_t i;
+
+
+ if(transaction == RIOPACKET_TRANSACTION_WRITE_NWRITE)
+ {
+ RIOPACKET_getNwrite(packet, &destId, &srcId, &address, &payloadSize, payload);
+
+ index = sprintf(&buffer[0],
+ "NWRITE: dstid=%04x srcid=%04x address=%08x payloadSize=%04x",
+ destId, srcId, address, payloadSize);
+ for(i = 0; i < payloadSize; i++)
+ {
+ index += sprintf(&buffer[index], "%02x", payload[i]);
+ }
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_WRITE_NWRITER)
+ {
+ RIOPACKET_getNwriteR(packet, &destId, &srcId, &tid, &address, &payloadSize, payload);
+
+ index = sprintf(&buffer[0],
+ "NWRITER: dstid=%04x srcid=%04x tid=%02x address=%08x payloadSize=%04x",
+ destId, srcId, tid, address, payloadSize);
+ for(i = 0; i < payloadSize; i++)
+ {
+ index += sprintf(&buffer[index], "%02x", payload[i]);
+ }
+ }
+ else
+ {
+ sprintf(buffer, "UNKNOWN:ftype=%02x transaction=%02x", ftype, transaction);
+ }
+ }
+ break;
+
+ case RIOPACKET_FTYPE_MAINTENANCE:
+ /**************************************************************************************
+ * A maintenance packet has been received.
+ **************************************************************************************/
+ {
+ uint8_t hop;
+ uint32_t offset;
+ uint32_t data;
+
+
+ /* Check the transaction to determine the type. */
+ if(transaction == RIOPACKET_TRANSACTION_MAINT_READ_REQUEST)
+ {
+ /* Maintenance read request. */
+ RIOPACKET_getMaintReadRequest(packet, &destId, &srcId, &hop, &tid, &offset);
+ sprintf(buffer,
+ "MAINTREADREQUEST: dstid=%04x srcid=%04x tid=%02x hop=%02x offset=%08x",
+ destId, srcId, tid, hop, offset);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_MAINT_WRITE_REQUEST)
+ {
+ /* Maintenance write request. */
+ RIOPACKET_getMaintWriteRequest(packet, &destId, &srcId, &hop, &tid, &offset, &data);
+ sprintf(buffer,
+ "MAINTWRITEREQUEST: dstid=%04x srcid=%04x tid=%02x hop=%02x offset=%08x data=%08x",
+ destId, srcId, tid, hop, offset, data);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_MAINT_READ_RESPONSE)
+ {
+ /* Maintenance read response. */
+ RIOPACKET_getMaintReadResponse(packet, &destId, &srcId, &tid, &data);
+ sprintf(buffer,
+ "MAINTREADRESPONSE: dstid=%04x srcid=%04x tid=%02x data=%08x",
+ destId, srcId, tid, data);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_MAINT_WRITE_RESPONSE)
+ {
+ /* Maintenance write repsonse. */
+ RIOPACKET_getMaintWriteResponse(packet, &destId, &srcId, &tid);
+ sprintf(buffer,
+ "MAINTWRITERESPONSE: dstid=%04x srcid=%04x tid=%02x",
+ destId, srcId, tid);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_MAINT_PORT_WRITE_REQUEST)
+ {
+ uint32_t componentTag;
+ uint32_t portErrorDetect;
+ uint32_t implementationSpecific;
+ uint8_t portId;
+ uint32_t logicalTransportErrorDetect;
+
+ /* Maintenance port write packet. */
+ RIOPACKET_getMaintPortWrite(packet, &destId, &srcId,
+ &componentTag, &portErrorDetect, &implementationSpecific,
+ &portId, &logicalTransportErrorDetect);
+ sprintf(buffer,
+ "MAINTPORTWRITE: dstid=%04x srcid=%04x componentTag=%08x portErrorDetect=%08x"
+ "implementationSpecific=%08x portId=%02x logicalTransportErrorDetect=%08x",
+ destId, srcId, componentTag, portErrorDetect, implementationSpecific, portId,
+ logicalTransportErrorDetect);
+ }
+ else
+ {
+ sprintf(buffer, "UNKNOWN:ftype=%02x transaction=%02x", ftype, transaction);
+ }
+ }
+ break;
+
+ case RIOPACKET_FTYPE_DOORBELL:
+ /**************************************************************************************
+ * A doorbell packet has been received.
+ **************************************************************************************/
+ {
+ uint16_t info;
+
+
+ RIOPACKET_getDoorbell(packet, &destId, &srcId, &tid, &info);
+ sprintf(buffer,
+ "DOORBELL: dstid=%04x srcid=%04x tid=%02x info=%04x",
+ destId, srcId, tid, info);
+ }
+ break;
+
+ case RIOPACKET_FTYPE_MESSAGE:
+ /**************************************************************************************
+ * A messaget has been received.
+ **************************************************************************************/
+ {
+ uint16_t payloadSize;
+ uint8_t payload[256];
+ uint32_t index;
+ uint32_t i;
+
+
+ RIOPACKET_getMessage(packet, &destId, &srcId, &tid, &payloadSize, payload);
+
+ index = sprintf(&buffer[0],
+ "MESSAGE: dstid=%04x srcid=%04x mailbox=%02x payloadSize=%04x",
+ destId, srcId, tid, payloadSize);
+ for(i = 0; i < payloadSize; i++)
+ {
+ index += sprintf(&buffer[index], "%02x", payload[i]);
+ }
+ }
+ break;
+
+ case RIOPACKET_FTYPE_RESPONSE:
+ /**************************************************************************************
+ * A response packet has been received.
+ **************************************************************************************/
+ {
+ uint8_t status;
+ uint16_t payloadSize;
+ uint8_t payload[256];
+
+
+ if(transaction == RIOPACKET_TRANSACTION_RESPONSE_NO_PAYLOAD)
+ {
+ RIOPACKET_getResponseNoPayload(packet, &destId, &srcId, &tid, &status);
+ sprintf(buffer,
+ "RESPONSENOPAYLOAD: dstid=%04x srcid=%04x tid=%02x status=%02x",
+ destId, srcId, tid, status);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_RESPONSE_MESSAGE_RESPONSE)
+ {
+ RIOPACKET_getResponseMessage(packet, &destId, &srcId, &tid, &status);
+ sprintf(buffer,
+ "RESPONSEMESSAGE: dstid=%04x srcid=%04x mailbox=%02x status=%02x",
+ destId, srcId, tid, status);
+ }
+ else if(transaction == RIOPACKET_TRANSACTION_RESPONSE_WITH_PAYLOAD)
+ {
+ uint32_t i;
+ uint32_t index;
+
+
+ RIOPACKET_getResponseWithPayload(packet, &destId, &srcId, &tid, 0, &payloadSize, payload);
+
+ index = sprintf(&buffer[0],
+ "RESPONSEWITHPAYLOAD: dstid=%04x srcid=%04x tid=%02x payloadSize=%04x ",
+ destId, srcId, tid, payloadSize);
+ for(i = 0; i < payloadSize; i++)
+ {
+ index += sprintf(&buffer[index], "%02x", payload[i]);
+ }
+ }
+ else
+ {
+ sprintf(buffer, "UNKNOWN:ftype=%02x transaction=%02x", ftype, transaction);
+ }
+ }
+ break;
+
+ default:
+ /**************************************************************************************
+ * Unsupported ftype.
+ **************************************************************************************/
+ sprintf(buffer, "UNKNOWN:ftype=%02x transaction=%02x", ftype, transaction);
+ break;
+ }
+
+ return;
+}
+#endif
+
+
+/**
+ * \brief Return the ftype of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The ftype of the packet.
+ *
+ * This function gets the ftype of a packet.
+ */
+uint8_t RIOPACKET_getFtype(RioPacket_t *packet)
+{
+ return FTYPE_GET(packet->payload);
+}
+
+
+/**
+ * \brief Return the destination deviceId of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The destination deviceId of the packet.
+ *
+ * This function gets the destination deviceId of a packet.
+ */
+uint16_t RIOPACKET_getDestination(RioPacket_t *packet)
+{
+ return DESTID_GET(packet->payload);
+}
+
+
+/**
+ * \brief Return the source deviceId of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The source deviceId of the packet.
+ *
+ * This function gets the source deviceId of a packet.
+ */
+uint16_t RIOPACKET_getSource(RioPacket_t *packet)
+{
+ return SRCID_GET(packet->payload);
+}
+
+
+/**
+ * \brief Return the transaction of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The transaction of the packet.
+ *
+ * This function gets the transaction field of a packet.
+ *
+ * \note Not all packets contain a transaction field.
+ */
+uint8_t RIOPACKET_getTransaction(RioPacket_t *packet)
+{
+ return TRANSACTION_GET(packet->payload);
+}
+
+
+/**
+ * \brief Return the transaction identifier of a packet.
+ *
+ * \param[in] packet The packet to operate on.
+ * \return The transaction identifier of the packet.
+ *
+ * This function gets the transaction identifier field of a packet.
+ *
+ * \note Not all packets contain a transaction identifier field.
+ */
+uint8_t RIOPACKET_getTid(RioPacket_t *packet)
+{
+ return TID_GET(packet->payload);
+}
+
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-READ functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set the packet to contain a maintenance read request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] hop The hop_count to set in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ * \param[in] offset The byte address in the configuration space to read.
+ *
+ * This function sets the content of a packet to a maintenance read request packet containing
+ * a request to read one word in configuration space.
+ *
+ */
+void RIOPACKET_setMaintReadRequest(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId, uint8_t hop,
+ uint8_t tid, uint32_t offset)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted but must be set to zero. */
+ content = 0x00180000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_MAINT_READ_REQUEST << 12;
+ content |= (uint32_t) 8ul << 8;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
+ content = ((uint32_t) hop) << 24;
+ content |= offset & 0x00fffffcul;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[3] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 4;
+}
+
+
+/**
+ * \brief Get entries from a maintenance read request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] hop The hop_count in this packet.
+ * \param[out] tid The transaction id to be returned in the response to this request.
+ * \param[out] offset The byte address in the configuration space to read.
+ *
+ * This function returns the content of a packet as if it contained a maintenance read
+ * request packet.
+ *
+ * \note Use the ftype and transaction fields to see if the packet is indeed a
+ * maintenance read request.
+ * \note If the packet does not contain a maintenance read request, the result
+ * will be undefined.
+ */
+void RIOPACKET_getMaintReadRequest(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId, uint8_t *hop,
+ uint8_t *tid, uint32_t *offset)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *hop = HOP_GET(packet->payload);
+ *offset = CONFIG_OFFSET_GET(packet->payload);
+}
+
+
+/**
+ * \brief Set the packet to contain a maintenance read response.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ * \param[in] data The data to send in the packet.
+ *
+ * This function sets the content of a packet to a maintanance read response packet
+ * containing a response to a request reading one word in configuration space.
+ */
+void RIOPACKET_setMaintReadResponse(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint32_t data)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00180000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|srcTID(7:0) */
+ content = (uint32_t) srcId << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_MAINT_READ_RESPONSE << 12;
+ content |= (uint32_t) RIOPACKET_RESPONSE_STATUS_DONE << 8;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* hopcount(7:0)|reserved(23:0) */
+ /* HopCount should always be set to 0xff in responses. */
+ content = 0xff000000ul;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* double-word 0 */
+ /* Note that both words are filled in to avoid looking at the offset. The receiver will not
+ look at the other part anyway. The standard does not say anything about the value of the padding. */
+ content = data;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[3] = content;
+ content = data;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[4] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[5] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 6;
+}
+
+
+/**
+ * \brief Get entries from a maintenance read response.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction identifier in the response.
+ * \param[out] data The data in the response.
+ *
+ * This function returns the content of a packet as if it contained a maintenance
+ * read response packet.
+ *
+ * \note Use the ftype and transaction fields to see if the packet is indeed a
+ * maintenance read response.
+ * \note If the packet does not contain a maintenance read response, the result
+ * will be undefined.
+ */
+void RIOPACKET_getMaintReadResponse(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint32_t *data)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *data = DOUBLE_WORD_MSB_GET(packet->payload, 0) | DOUBLE_WORD_LSB_GET(packet->payload, 0);
+}
+
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-WRITE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set the packet to contain a maintenance write request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] hop The hop_count to set in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ * \param[in] offset The byte address in the configuration space to write to.
+ * \param[in] data The data to write in configuration space.
+ *
+ * This function sets the content of a packet to a maintenance write request packet
+ * containing a request to write one word in configuration space.
+ */
+void RIOPACKET_setMaintWriteRequest(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId, uint8_t hop,
+ uint8_t tid, uint32_t offset, uint32_t data)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00180000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_MAINT_WRITE_REQUEST << 12;
+ content |= (uint32_t) 8ul << 8;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* hopcount(7:0)|configOffset(20:0)|wdptr|reserved(1:0) */
+ content = ((uint32_t) hop) << 24;
+ content |= offset & 0x00fffffcul;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* double-word 0 */
+ /* Note that both words are filled in to avoid looking at the offset. The receiver will not
+ look at the other part anyway. The standard does not say anything about the value of the padding. */
+ content = data;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[3] = content;
+ content = data;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[4] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[5] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 6;
+}
+
+
+/**
+ * \brief Get entries from a maintenance write request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] hop The hop_count in this packet.
+ * \param[out] tid The transaction id in this packet.
+ * \param[out] offset The byte address in the configuration space to read.
+ * \param[out] data The data to requested to be written in configuration space.
+ *
+ * This function returns the content of a packet as if it contained a maintenance write
+ * request packet.
+ *
+ * \note Use the ftype and transaction fields to see if the packet is indeed a
+ * maintenance write request.
+ * \note If the packet does not contain a maintenance write request, the result
+ * will be undefined.
+ */
+void RIOPACKET_getMaintWriteRequest(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId, uint8_t *hop,
+ uint8_t *tid, uint32_t *offset, uint32_t *data)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *hop = HOP_GET(packet->payload);
+ *offset = CONFIG_OFFSET_GET(packet->payload);
+ *data = DOUBLE_WORD_MSB_GET(packet->payload, 0) | DOUBLE_WORD_LSB_GET(packet->payload, 0);
+}
+
+
+/**
+ * \brief Set the packet to contain a maintenance write response.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ *
+ * This function sets the content of a packet to a maintanance write response packet
+ * containing a response to a request writing one word in configuration space.
+ */
+void RIOPACKET_setMaintWriteResponse(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00180000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_MAINT_WRITE_RESPONSE << 12;
+ content |= (uint32_t) RIOPACKET_RESPONSE_STATUS_DONE << 8;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* hopcount(7:0)|reserved(23:0) */
+ /* HopCount should always be set to 0xff in responses. */
+ content = 0xff000000ul;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[3] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 4;
+}
+
+
+/**
+ * \brief Get entries from a maintenance write response.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction identifier in the response.
+ *
+ * This function returns the content of a packet as if it contained a maintenance
+ * write response packet.
+ *
+ * \note Use the ftype and transaction fields to see if the packet is indeed a
+ * maintenance write response.
+ * \note If the packet does not contain a maintenance write response, the result
+ * will be undefined.
+ */
+void RIOPACKET_getMaintWriteResponse(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+}
+
+
+/*******************************************************************************************
+ * Logical I/O MAINTENANCE-PORTWRITE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set the packet to contain a maintenance port-write request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] componentTag The value of the componentTag register to set in the packet.
+ * \param[in] portErrorDetect The value of the Port N Error Detect CSR to set in the packet.
+ * \param[in] implementationSpecific An implementation specific value to set in the packet.
+ * \param[in] portId The port ID of the port to set in the packet.
+ * \param[in] logicalTransportErrorDetect The value of the Logical/Transport Layer
+ * Error Detect CSR to set in the packet.
+ *
+ * This function sets the content of a packet to a maintenance port-write request packet.
+ */
+void RIOPACKET_setMaintPortWrite(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint32_t componentTag, uint32_t portErrorDetect,
+ uint32_t implementationSpecific, uint8_t portId,
+ uint32_t logicalTransportErrorDetect)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00180000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = (uint32_t) srcId << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_MAINT_PORT_WRITE_REQUEST << 12;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* hopcount(7:0)|reserved(23:0) */
+ content = 0x00000000ul;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* double-word 0 */
+ content = componentTag;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[3] = content;
+ content = portErrorDetect;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[4] = content;
+
+ /* double-word 1 */
+ content = implementationSpecific << 8;
+ content |= (uint32_t) portId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[5] = content;
+ content = logicalTransportErrorDetect;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[6] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[7] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 8;
+}
+
+
+/**
+ * \brief Get entries from a maintenance port-write request.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The device id of the destination end point.
+ * \param[out] srcId The device id of the source end point.
+ * \param[out] componentTag The value of the componentTag register in this packet.
+ * \param[out] portErrorDetect The value of the Port N Error Detect CSR in this packet.
+ * \param[out] implementationSpecific An implementation specific value in this packet.
+ * \param[out] portId The port ID of the port in this packet.
+ * \param[out] logicalTransportErrorDetect The value of the Logical/Transport Layer
+ * Error Detect CSR in this packet.
+ *
+ * This function returns the content of a packet as if it contained a maintenance port-write
+ * request packet.
+ *
+ * \note Use the ftype and transaction fields to see if the packet is indeed a
+ * maintenance port-write request.
+ * \note If the packet does not contain a maintenance port-write request, the result
+ * will be undefined.
+ */
+void RIOPACKET_getMaintPortWrite(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint32_t *componentTag, uint32_t *portErrorDetect,
+ uint32_t *implementationSpecific, uint8_t *portId,
+ uint32_t *logicalTransportErrorDetect)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *componentTag = packet->payload[3];
+ *portErrorDetect = packet->payload[4];
+ *implementationSpecific = packet->payload[5] >> 8;
+ *portId = (uint8_t) (packet->payload[5] & 0xff);
+ *logicalTransportErrorDetect = packet->payload[6];
+}
+
+
+/*******************************************************************************************
+ * Logical I/O NWRITE/NWRITER functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set a packet to contain an NWRITE.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] address The byte address in IO-space to write to.
+ * \param[in] payloadSize The number of bytes to write. The largest allowed size is 256 bytes.
+ * \param[in] payload A pointer to the array of bytes to write.
+ *
+ * This function sets the content of a packet to an NWRITE containing a request
+ * to write the number of bytes specified by payloadSize to the address specified by the
+ * address argument.
+ *
+ * \note The address is a byte address.
+ *
+ * \note Not all combinations of addresses and sizes are allowed. The packet will be empty
+ * if an unallowed address/payloadSize combination is used. Use RIOPACKET_getWritePacketSize()
+ * to get the maximum size to use based on the address and payloadSize.
+ */
+void RIOPACKET_setNwrite(RioPacket_t *packet, uint16_t destId, uint16_t srcId,
+ uint32_t address, uint16_t payloadSize, uint8_t *payload)
+{
+ uint32_t content;
+ uint16_t wrsize;
+
+
+ /* Convert the address and size to the wrsize field and check if the combination is valid. */
+ wrsize = wrsizeGet(address, payloadSize);
+ if(wrsize != 0xffff)
+ {
+ /* The address and size field combination is valid. */
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00150000ul;
+ content |= (uint32_t) destId;
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|wrsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_WRITE_NWRITE << 12;
+ content |= (uint32_t) (wrsize & 0x0f00);
+ packet->payload[1] = content;
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* wrsize also contains wdptr in the lower nibble. */
+ /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
+ 34-bit address should be used, another mechanism to set it should be used. */
+ content = (address & 0xfffffff8ul);
+ content |= ((uint32_t) (wrsize & 0x000f)) << 2;
+ packet->payload[2] = content;
+
+ /* Place the payload buffer into the payload of the packet. */
+ /* This function also calculates the CRC. */
+ packet->size = setPacketPayload(&(packet->payload[0]), 12, address & 0x7, payloadSize, payload);
+ }
+ else
+ {
+ /* The address and size field combination is not valid. */
+ /* Cannot create a packet from these arguments, indicate this by setting the packet size to zero. */
+ packet->size = 0;
+ }
+}
+
+
+/**
+ * \brief Get entries from a NWRITE.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] address The byte address into IO-space requested to be written.
+ * \param[out] payloadSize The number of bytes requested to be written.
+ * \param[out] payload The data requested to be written.
+ *
+ * This function returns the content of a packet as if it contained an NWRITE.
+ *
+ * \note The address is a byte address.
+ *
+ * \note Any padding contained in double-word0 will be removed and the content
+ * will be placed where the payload pointer is pointing.
+ */
+void RIOPACKET_getNwrite(RioPacket_t *packet, uint16_t *destId, uint16_t *srcId,
+ uint32_t *address, uint16_t *payloadSize, uint8_t *payload)
+{
+ uint8_t wrsize;
+ uint8_t wdptr;
+ uint8_t offset = 0;
+ uint16_t size = 0;
+
+
+ wrsize = WRSIZE_GET(packet->payload);
+ wdptr = WDPTR_GET(packet->payload);
+ wrsizeToOffset(wrsize, wdptr, &offset, &size);
+
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *address = ADDRESS_GET(packet->payload) | offset;
+
+ if(size > 16)
+ {
+ size = 4*(packet->size-4);
+ }
+ else
+ {
+ /* The size already contains the correct value. */
+ }
+
+
+ *payloadSize = getPacketPayload(&(packet->payload[0]), 12, offset, size, payload);
+}
+
+
+
+/**
+ * \brief Set a packet to contain an NWRITER.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ * \param[in] address The byte address in IO-space to write to.
+ * \param[in] payloadSize The number of bytes to write. The largest allowed size is 256 bytes.
+ * \param[in] payload A pointer to the array of bytes to write.
+ *
+ * This function sets the content of a packet to an NWRITER containing a request
+ * to write the number of bytes specified by payloadSize to the address specified by the
+ * address argument. This packet requires a RESPONSE containing the transaction identifier
+ * specified in this packet.
+ *
+ * \note The address is a byte address.
+ *
+ * \note Not all combinations of addresses and sizes are allowed. The packet will be empty
+ * if an unallowed address/payloadSize combination is used. Use RIOPACKET_getWritePacketSize()
+ * to get the maximum size to use based on the address and payloadSize.
+ */
+void RIOPACKET_setNwriteR(RioPacket_t *packet, uint16_t destId, uint16_t srcId, uint8_t tid,
+ uint32_t address, uint16_t payloadSize, uint8_t *payload)
+{
+ uint32_t content;
+ uint16_t wrsize;
+
+
+ /* Convert the address and size to the wrsize field and check if the combination is valid. */
+ wrsize = wrsizeGet(address, payloadSize);
+ if(wrsize != 0xffff)
+ {
+ /* The address and size field combination is valid. */
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00150000ul;
+ content |= (uint32_t) destId;
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|wrsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) RIOPACKET_TRANSACTION_WRITE_NWRITER << 12;
+ content |= (uint32_t) (wrsize & 0x0f00);
+ content |= (uint32_t) tid;
+ packet->payload[1] = content;
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* wrsize also contains wdptr in the lower nibble. */
+ /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
+ 34-bit address should be used, another mechanism to set it should be used. */
+ content = (address & 0xfffffff8ul);
+ content |= ((uint32_t) (wrsize & 0x000f)) << 2;
+ packet->payload[2] = content;
+
+ /* Place the payload buffer into the payload of the packet. */
+ /* This function also calculates the CRC. */
+ packet->size = setPacketPayload(&(packet->payload[0]), 12, address & 0x7, payloadSize, payload);
+ }
+ else
+ {
+ /* The address and size field combination is not valid. */
+ /* Cannot create a packet from these arguments, indicate this by setting the packet size to zero. */
+ packet->size = 0;
+ }
+}
+
+
+/**
+ * \brief Get entries from a NWRITER.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction id in this packet.
+ * \param[out] address The byte address into IO-space requested to be written.
+ * \param[out] payloadSize The number of bytes requested to be written.
+ * \param[out] payload The data requested to be written.
+ *
+ * This function returns the content of a packet as if it contained an NWRITER.
+ *
+ * \note The address is a byte address.
+ *
+ * \note Any padding contained in double-word0 will be removed and the content
+ * will be placed where the payload pointer is pointing.
+ */
+void RIOPACKET_getNwriteR(RioPacket_t *packet, uint16_t *destId, uint16_t *srcId, uint8_t *tid,
+ uint32_t *address, uint16_t *payloadSize, uint8_t *payload)
+{
+ uint8_t wrsize;
+ uint8_t wdptr;
+ uint8_t offset = 0;
+ uint16_t size = 0;
+
+
+ wrsize = WRSIZE_GET(packet->payload);
+ wdptr = WDPTR_GET(packet->payload);
+ wrsizeToOffset(wrsize, wdptr, &offset, &size);
+
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *address = ADDRESS_GET(packet->payload) | offset;
+
+ if(size > 16)
+ {
+ size = 4*(packet->size-4);
+ }
+ else
+ {
+ /* The size already contains the correct value. */
+ }
+
+ *payloadSize = getPacketPayload(&(packet->payload[0]), 12, offset, size, payload);
+}
+
+
+/*******************************************************************************************
+ * Logical I/O NREAD functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set a packet to contain an NREAD.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction id to set in the response.
+ * \param[in] address The byte address to read from.
+ * \param[in] payloadSize The number of bytes to read. The largest allowed size is 256 bytes.
+ *
+ * This function sets the content of a packet to an NREAD containing a request
+ * to read the number of bytes specified by payloadSize from the address specified by the
+ * address argument.
+ *
+ * \note The address is a byte address.
+ *
+ * \note Not all combinations of address and length are allowed. The packet will be empty
+ * if an unallowed address/payloadSize combination is used. Use RIOPACKET_getReadPacketSize()
+ * to get the maximum size to use based on the address and payloadSize.
+ */
+void RIOPACKET_setNread(RioPacket_t *packet, uint16_t destId, uint16_t srcId, uint8_t tid,
+ uint32_t address, uint16_t payloadSize)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+ uint16_t rdsize;
+
+
+ /* Convert the address and size to the rdsize field and check if the combination is valid. */
+ rdsize = rdsizeGet(address, payloadSize);
+ if(rdsize != 0xffff)
+ {
+ /* The address and size field combination is valid. */
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x00120000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|rdsize(3:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= ((uint32_t) RIOPACKET_TRANSACTION_REQUEST_NREAD) << 12;
+ content |= (uint32_t) (rdsize & 0x0f00);
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* address(28:0)|wdptr|xamsbs(1:0) */
+ /* rdsize also contains wdptr in the lower nibble. */
+ /* REMARK: Note that xamsbs cannot be used if the address is a word. If the 2 msb bits in the
+ 34-bit address should be used, another mechanism to set it should be used. */
+ content = address & 0xfffffff8ul;
+ content |= ((uint32_t) (rdsize & 0x000f)) << 2;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[2] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[3] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 4;
+ }
+ else
+ {
+ /* The address and size field combination is not valid. */
+ /* Cannot create a packet from these arguments, indicate this by setting the packet size to zero. */
+ packet->size = 0;
+ }
+}
+
+
+/**
+ * \brief Get entries from an NREAD.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction id in this packet.
+ * \param[out] address The byte address into IO-space requested to be written.
+ * \param[out] payloadSize The number of bytes requested to be read.
+ *
+ * This function returns the content of a packet as if it contained an NREAD.
+ *
+ * \note The address is a byte address.
+ */
+void RIOPACKET_getNread(RioPacket_t *packet, uint16_t *destId, uint16_t *srcId, uint8_t *tid,
+ uint32_t *address, uint16_t *payloadSize)
+{
+ uint8_t rdsize;
+ uint8_t wdptr;
+ uint8_t offset = 0;
+ uint16_t size = 0;
+
+
+ rdsize = WRSIZE_GET(packet->payload);
+ wdptr = WDPTR_GET(packet->payload);
+ rdsizeToOffset(rdsize, wdptr, &offset, &size);
+
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *address = ADDRESS_GET(packet->payload) | offset;
+ *payloadSize = size;
+}
+
+
+
+/*******************************************************************************************
+ * Logical message passing DOORBELL and MESSAGE functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set a packet to contain a DOORBELL.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction identifier to set in the packet.
+ * \param[in] info The information to send with the doorbell.
+ *
+ * This function sets the content of a packet to a DOORBELL.
+ */
+void RIOPACKET_setDoorbell(RioPacket_t *packet, uint16_t destId, uint16_t srcId, uint8_t tid,
+ uint16_t info)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001a0000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|rsrv(7:0)|srcTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* infoMSB(7:0)|infoLSB(7:0)|crc(15:0) */
+ content = ((uint32_t) info) << 16;
+ crc = RIOPACKET_Crc16(info, crc);
+ content |= crc;
+ packet->payload[2] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 3;
+}
+
+
+/**
+ * \brief Get entries from a DOORBELL.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction identifier in this packet.
+ * \param[out] info The information field in this packet.
+ *
+ * This function returns the content of a packet as if it contained a DOORBELL.
+ */
+void RIOPACKET_getDoorbell(RioPacket_t *packet, uint16_t *destId, uint16_t *srcId, uint8_t *tid,
+ uint16_t *info)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *info = INFO_GET(packet->payload);
+}
+
+
+/**
+ * \brief Set a packet to contain a MESSAGE.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] mailbox The mailbox to send the message to.
+ * \param[in] payloadSize The number of bytes to place into the message.
+ * \param[in] payload A pointer to the array of bytes to place into the message.
+ *
+ * This function sets the content of a packet to contain a MESSAGE.
+ *
+ * \note The mailbox argument maps to the packet fields as:
+ * {xmbox(3:0), letter(1:0), mbox(1:0)} which means that mailbox 0-15 can support
+ * multipacket messages and 16-255 can handle only single packet messages.
+ *
+ * \note The payload size has to be larger than zero and less than 256.
+ *
+ * \note Only payloads of even double-words are supported by the protocol itself. Payload
+ * that is shorter will be padded.
+ */
+void RIOPACKET_setMessage(RioPacket_t *packet, uint16_t destId, uint16_t srcId, uint8_t mailbox,
+ uint16_t payloadSize, uint8_t *payload)
+{
+ uint32_t content;
+
+
+ /* Make sure that the message payload size is larger than zero. */
+ if((payloadSize > 0) && (payloadSize <= 256))
+ {
+ /* The payload size is larger than zero. */
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001b0000ul;
+ content |= (uint32_t) destId;
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|msglen(3:0)|ssize(3:0)|letter(1:0)|mbox(1:0)|msgseg(3:0)/xmbox(3:0) */
+ content = ((uint32_t) srcId) << 16;
+ if(payloadSize <= 8u)
+ {
+ content |= 0x00000900ul;
+ }
+ else if(payloadSize <= 16u)
+ {
+ content |= 0x00000a00ul;
+ }
+ else if(payloadSize <= 32u)
+ {
+ content |= 0x00000b00ul;
+ }
+ else if(payloadSize <= 64u)
+ {
+ content |= 0x00000c00ul;
+ }
+ else if(payloadSize <= 128u)
+ {
+ content |= 0x00000d00ul;
+ }
+ else
+ {
+ content |= 0x00000e00ul;
+ }
+ content |= (((uint32_t) mailbox) & 0xful) << 4;
+ content |= ((uint32_t) mailbox) >> 4;
+ packet->payload[1] = content;
+
+ /* Place data buffer into the payload of the packet and set the size. */
+ packet->size = setPacketPayload(&(packet->payload[0]), 8, 0, payloadSize, payload);
+ }
+ else
+ {
+ /* The payload size is not allowed. */
+ /* Unable to create the new packet. */
+ packet->size = 0;
+ }
+}
+
+
+/**
+ * \brief Get entries from a MESSAGE.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] mailbox The mailbox the message is received on.
+ * \param[out] payloadSize The number of bytes in the payload.
+ * \param[out] payload The payload of the packet.
+ *
+ * This function returns the content of a packet as if it contained a MESSAGE.
+ *
+ * \note The mailbox argument maps to the packet fields as:
+ * {xmbox(3:0), letter(1:0), mbox(1:0)} which means that mailbox 0-15 can support
+ * multipacket messages and 16-255 can handle only single packet messages.
+ *
+ * \note Only payloads of even double-words are supported by the protocol itself so the
+ * returned payloadSize is always an even multiple of eight.
+ */
+void RIOPACKET_getMessage(RioPacket_t *packet, uint16_t *destId, uint16_t *srcId, uint8_t *mailbox,
+ uint16_t *payloadSize, uint8_t *payload)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *mailbox = XMBOX_GET(packet->payload);
+ *mailbox <<= 2;
+ *mailbox |= LETTER_GET(packet->payload);
+ *mailbox <<= 2;
+ *mailbox |= MBOX_GET(packet->payload);
+ *payloadSize = getPacketPayload(&(packet->payload[0]), 8, 0, (packet->size-3)*4, payload);
+}
+
+
+
+
+/*******************************************************************************************
+ * Logical I/O RESPONSE-DONE-PAYLOAD, RESPONSE-DONE, RESPONSE-RETRY and RESPONSE-ERROR
+ * functions.
+ *******************************************************************************************/
+
+/**
+ * \brief Set a packet to contain a RESPONSE without payload.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction id to send the response for.
+ * \param[in] status The status to send in the packet.
+ *
+ * This function sets the content of a packet to contain a RESPONSE without payload.
+ *
+ * \note The tid field must be the same value as the packet contained that this is the
+ * response for.
+ *
+ * \note The status field should be either of the values RIOPACKET_RESPONSE_STATUS_XXXX.
+ */
+void RIOPACKET_setResponseNoPayload(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint8_t status)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001d0000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= ((uint32_t) RIOPACKET_TRANSACTION_RESPONSE_NO_PAYLOAD) << 12;
+ content |= ((uint32_t) (status & 0xf)) << 8;
+ content |= (uint32_t) tid;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[2] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 3;
+}
+
+
+/**
+ * \brief Get entries from a RESPONSE without payload.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction identifier in this packet.
+ * \param[out] status The status in this packet.
+ *
+ * This function returns the content of a packet as if it contained a RESPONSE.
+ */
+void RIOPACKET_getResponseNoPayload(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint8_t *status)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *status = STATUS_GET(packet->payload);
+}
+
+
+
+/**
+ * \brief Set a packet to contain a RESPONSE also containing payload.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] tid The transaction id to send the response for.
+ * \param[in] offset The offset into the payload to start to write the input payload to.
+ * \param[in] payloadSize The size of the payload to return in the reply.
+ * \param[in] payload The payload to return in the reply.
+ *
+ * This function sets the content of a packet to contain a RESPOSE with payload.
+ *
+ * \note The tid field must be the same value as the packet contained that this is the
+ * response for.
+ *
+ * \note The offset field can be used to offset the payload in a response to, for
+ * example, an NREAD.
+ *
+ * \note The payloadSize must match the size of the packet that this is the
+ * response for.
+ */
+void RIOPACKET_setResponseWithPayload(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint8_t offset,
+ uint16_t payloadSize, uint8_t *payload)
+{
+ uint32_t content;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001d0000ul;
+ content |= (uint32_t) destId;
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|targetTID(7:0) */
+ /* status=DONE is 0. */
+ content = ((uint32_t) srcId) << 16;
+ content |= ((uint32_t) RIOPACKET_TRANSACTION_RESPONSE_WITH_PAYLOAD) << 12;
+ content |= (uint32_t) tid;
+ packet->payload[1] = content;
+
+ packet->size = setPacketPayload(&(packet->payload[0]), 8, offset & 0x7, payloadSize, payload);
+}
+
+/**
+ * \brief Get entries from a RESPONSE containing payload.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] tid The transaction identifier in this packet.
+ * \param[in] offset The offset into the payload to start reading from.
+ * \param[out] payloadSize The number of bytes in the payload.
+ * \param[out] payload The payload of the packet.
+ *
+ * This function returns the content of a packet as if it contained a RESPONSE with payload.
+ *
+ * \note The offset field can be used to read the payload in a response to, for
+ * example, an NREAD.
+ */
+void RIOPACKET_getResponseWithPayload(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint8_t offset,
+ uint16_t *payloadSize, uint8_t *payload)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *tid = TID_GET(packet->payload);
+ *payloadSize = getPacketPayload(&(packet->payload[0]), 8, offset & 0x7, (packet->size-3)*4, payload);
+}
+
+
+
+/**
+ * \brief Set a packet to contains a RESPONSE to a message.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[in] destId The deviceId to use as destination in the packet.
+ * \param[in] srcId The deviceId to use as source in the packet.
+ * \param[in] mailbox The mailbox to send the message to.
+ * \param[in] status The status to send in the packet.
+ *
+ * This function is used to send a response indicating a successfull
+ * completion in reply to a previously received packet.
+ *
+ * \note The mailbox field should contain the same value as the packet that this is the
+ * response to.
+ *
+ * \note The status field should be either of the values RIOPACKET_RESPONSE_STATUS_XXXX.
+ */
+void RIOPACKET_setResponseMessage(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t mailbox, uint8_t status)
+{
+ uint32_t content;
+ uint16_t crc = 0xffffu;
+
+
+ /* ackId(4:0)|0|vc|crf|prio(1:0)|tt(1:0)|ftype(3:0)|destinationId(15:0) */
+ /* ackId is set when the packet is transmitted. */
+ content = 0x001d0000ul;
+ content |= (uint32_t) destId;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[0] = content;
+
+ /* sourceId(15:0)|transaction(3:0)|status(3:0)|letter(1:0|mbox(1:0)|msgseg(3:0) */
+ content = ((uint32_t) srcId) << 16;
+ content |= ((uint32_t) RIOPACKET_TRANSACTION_RESPONSE_MESSAGE_RESPONSE) << 12;
+ content |= ((uint32_t) (status & 0xf)) << 8;
+ content |= ((uint32_t) (mailbox & 0xf)) << 4;
+ content |= ((uint32_t) mailbox) >> 4;
+ crc = RIOPACKET_Crc32(content, crc);
+ packet->payload[1] = content;
+
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ packet->payload[2] = content;
+
+ /* Set the size of the packet. */
+ packet->size = 3;
+}
+
+/**
+ * \brief Get entries from a RESPONSE to a message.
+ *
+ * \param[in] packet The packet to operate on.
+ * \param[out] destId The destination deviceId in this packet.
+ * \param[out] srcId The source deviceId in this packet.
+ * \param[out] mailbox The mailbox the response should be sent to.
+ * \param[out] status The status in the packet.
+ *
+ * This function returns the content of a packet as if it contained a RESPONSE to a message.
+ */
+void RIOPACKET_getResponseMessage(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *mailbox, uint8_t *status)
+{
+ *destId = DESTID_GET(packet->payload);
+ *srcId = SRCID_GET(packet->payload);
+ *mailbox = XMBOX_GET(packet->payload);
+ *mailbox <<= 2;
+ *mailbox |= LETTER_GET(packet->payload);
+ *mailbox <<= 2;
+ *mailbox |= MBOX_GET(packet->payload);
+ *status = STATUS_GET(packet->payload);
+}
+
+
+/**
+ * \brief Calculate a new CRC16 value.
+ *
+ * \param[in] data The new data (16-bit) to update the current crc value with.
+ * \param[in] crc The old crc value that should be updated.
+ * \returns The new crc value based on the input arguments.
+ *
+ * This function calculates a new crc value using the generator polynom
+ * P(X)=x16+x12+x5+1. It is defined in RapidIO 3.0 part6 chapter 2.4.2.
+ */
+uint16_t RIOPACKET_Crc16(const uint16_t data, const uint16_t crc)
+{
+ static const uint16_t crcTable[] = {
+ 0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50a5u, 0x60c6u, 0x70e7u,
+ 0x8108u, 0x9129u, 0xa14au, 0xb16bu, 0xc18cu, 0xd1adu, 0xe1ceu, 0xf1efu,
+ 0x1231u, 0x0210u, 0x3273u, 0x2252u, 0x52b5u, 0x4294u, 0x72f7u, 0x62d6u,
+ 0x9339u, 0x8318u, 0xb37bu, 0xa35au, 0xd3bdu, 0xc39cu, 0xf3ffu, 0xe3deu,
+ 0x2462u, 0x3443u, 0x0420u, 0x1401u, 0x64e6u, 0x74c7u, 0x44a4u, 0x5485u,
+ 0xa56au, 0xb54bu, 0x8528u, 0x9509u, 0xe5eeu, 0xf5cfu, 0xc5acu, 0xd58du,
+ 0x3653u, 0x2672u, 0x1611u, 0x0630u, 0x76d7u, 0x66f6u, 0x5695u, 0x46b4u,
+ 0xb75bu, 0xa77au, 0x9719u, 0x8738u, 0xf7dfu, 0xe7feu, 0xd79du, 0xc7bcu,
+ 0x48c4u, 0x58e5u, 0x6886u, 0x78a7u, 0x0840u, 0x1861u, 0x2802u, 0x3823u,
+ 0xc9ccu, 0xd9edu, 0xe98eu, 0xf9afu, 0x8948u, 0x9969u, 0xa90au, 0xb92bu,
+ 0x5af5u, 0x4ad4u, 0x7ab7u, 0x6a96u, 0x1a71u, 0x0a50u, 0x3a33u, 0x2a12u,
+ 0xdbfdu, 0xcbdcu, 0xfbbfu, 0xeb9eu, 0x9b79u, 0x8b58u, 0xbb3bu, 0xab1au,
+ 0x6ca6u, 0x7c87u, 0x4ce4u, 0x5cc5u, 0x2c22u, 0x3c03u, 0x0c60u, 0x1c41u,
+ 0xedaeu, 0xfd8fu, 0xcdecu, 0xddcdu, 0xad2au, 0xbd0bu, 0x8d68u, 0x9d49u,
+ 0x7e97u, 0x6eb6u, 0x5ed5u, 0x4ef4u, 0x3e13u, 0x2e32u, 0x1e51u, 0x0e70u,
+ 0xff9fu, 0xefbeu, 0xdfddu, 0xcffcu, 0xbf1bu, 0xaf3au, 0x9f59u, 0x8f78u,
+ 0x9188u, 0x81a9u, 0xb1cau, 0xa1ebu, 0xd10cu, 0xc12du, 0xf14eu, 0xe16fu,
+ 0x1080u, 0x00a1u, 0x30c2u, 0x20e3u, 0x5004u, 0x4025u, 0x7046u, 0x6067u,
+ 0x83b9u, 0x9398u, 0xa3fbu, 0xb3dau, 0xc33du, 0xd31cu, 0xe37fu, 0xf35eu,
+ 0x02b1u, 0x1290u, 0x22f3u, 0x32d2u, 0x4235u, 0x5214u, 0x6277u, 0x7256u,
+ 0xb5eau, 0xa5cbu, 0x95a8u, 0x8589u, 0xf56eu, 0xe54fu, 0xd52cu, 0xc50du,
+ 0x34e2u, 0x24c3u, 0x14a0u, 0x0481u, 0x7466u, 0x6447u, 0x5424u, 0x4405u,
+ 0xa7dbu, 0xb7fau, 0x8799u, 0x97b8u, 0xe75fu, 0xf77eu, 0xc71du, 0xd73cu,
+ 0x26d3u, 0x36f2u, 0x0691u, 0x16b0u, 0x6657u, 0x7676u, 0x4615u, 0x5634u,
+ 0xd94cu, 0xc96du, 0xf90eu, 0xe92fu, 0x99c8u, 0x89e9u, 0xb98au, 0xa9abu,
+ 0x5844u, 0x4865u, 0x7806u, 0x6827u, 0x18c0u, 0x08e1u, 0x3882u, 0x28a3u,
+ 0xcb7du, 0xdb5cu, 0xeb3fu, 0xfb1eu, 0x8bf9u, 0x9bd8u, 0xabbbu, 0xbb9au,
+ 0x4a75u, 0x5a54u, 0x6a37u, 0x7a16u, 0x0af1u, 0x1ad0u, 0x2ab3u, 0x3a92u,
+ 0xfd2eu, 0xed0fu, 0xdd6cu, 0xcd4du, 0xbdaau, 0xad8bu, 0x9de8u, 0x8dc9u,
+ 0x7c26u, 0x6c07u, 0x5c64u, 0x4c45u, 0x3ca2u, 0x2c83u, 0x1ce0u, 0x0cc1u,
+ 0xef1fu, 0xff3eu, 0xcf5du, 0xdf7cu, 0xaf9bu, 0xbfbau, 0x8fd9u, 0x9ff8u,
+ 0x6e17u, 0x7e36u, 0x4e55u, 0x5e74u, 0x2e93u, 0x3eb2u, 0x0ed1u, 0x1ef0u
+ };
+
+ uint16_t result;
+ uint8_t index;
+
+ result = crc;
+ index = (uint8_t) ((data >> 8) ^ (result >> 8));
+ result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
+ index = (uint8_t) ((data) ^ (result >> 8));
+ result = (uint16_t) (crcTable[index] ^ (uint16_t)(result << 8));
+
+ return result;
+}
+
+
+/**
+ * \brief Calculate a new CRC16 value.
+ *
+ * \param[in] data The new data (32-bit) to update the current crc value with.
+ * \param[in] crc The old crc value that should be updated.
+ * \returns The new crc value based on the input arguments.
+ *
+ * This function calculates a new crc value using the generator polynom
+ * P(X)=x16+x12+x5+1. It is defined in RapidIO 3.0 part6 chapter 2.4.2.
+ */
+uint16_t RIOPACKET_Crc32(const uint32_t data, uint16_t crc)
+{
+ crc = RIOPACKET_Crc16((uint16_t) (data >> 16), crc);
+ crc = RIOPACKET_Crc16((uint16_t) (data), crc);
+ return crc;
+}
+
+
+/**
+ * \brief Get the maximum size of an NWRITE payload.
+ *
+ * \param[in] address The starting address to write to in the NWRITE.
+ * \param[in] size The total size of the access to NWRITE.
+ * \returns The maximum number of bytes that are allowed to send in a single
+ * NWRITE packet that conforms to the RapidIO standard.
+ *
+ * This function calculates the maximum sized NWRITE packet payload that are
+ * possible to send without breaking the limitations in the RapidIO specification.
+ * It is intended to be called repeatedly.
+ *
+ * Example: An area with address=0x00007 and size=258 needs to be written.
+ * Call RIOPACKET_getWritePacketSize(0x00007, 258)->1.
+ * Send an NWRITE to address=0x00007 and size=1.
+ * Update the address and size with the returned value->
+ * address+=1->address=0x00008 size-=1->size=257.
+ * Call RIOPACKET_getWritePacketSize(0x00008, 257)->256.
+ * Send an NWRITE to address=0x00008 and size=256.
+ * Update the address and size with the returned value->
+ * address+=256->address=0x00108 size-=256->size=1.
+ * Call RIOPACKET_getWritePacketSize(0x00108, 1)->1.
+ * Send an NWRITE to address=0x00108 and size=1.
+ * Update the address and size with the returned value->
+ * address+=1->address=0x00109 size-=1->size=0.
+ * All the data has been written.
+ *
+ */
+uint32_t RIOPACKET_getWritePacketSize(uint32_t address, uint32_t size)
+{
+ uint32_t returnValue;
+
+
+ switch(address%8)
+ {
+ case 0:
+ if(size >= 256)
+ {
+ returnValue = 256;
+ }
+ else if(size >= 8)
+ {
+ returnValue = size - (size % 8);
+ }
+ else
+ {
+ returnValue = size;
+ }
+ break;
+ case 1:
+ if(size >= 7)
+ {
+ returnValue = 7;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 2:
+ if(size >= 6)
+ {
+ returnValue = 6;
+ }
+ else if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 3:
+ if(size >= 5)
+ {
+ returnValue = 5;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 4:
+ if(size >= 4)
+ {
+ returnValue = 4;
+ }
+ else if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 5:
+ if(size >= 3)
+ {
+ returnValue = 3;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 6:
+ if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ default:
+ returnValue = 1;
+ break;
+ }
+
+ return returnValue;
+}
+
+
+/**
+ * \brief Get the maximum size of an NREAD payload.
+ *
+ * \param[in] address The starting address to read from in the NREAD.
+ * \param[in] size The total size of the access to NREAD.
+ * \returns The maximum number of bytes that are allowed to send in a single
+ * NREAD packet that conforms to the RapidIO standard.
+ *
+ * This function calculates the maximum sized NREAD packet payload that are
+ * possible to send without breaking the limitations in the RapidIO specification.
+ * It is intended to be called repeatedly.
+ *
+ * Example: An area with address=0x00007 and size=258 needs to be read.
+ * Call RIOPACKET_getReadPacketSize(0x00007, 258)->1.
+ * Send an NREAD to address=0x00007 and size=1.
+ * Update the address and size with the returned value->
+ * address+=1->address=0x00008 size-=1->size=257.
+ * Call RIOPACKET_getReadPacketSize(0x00008, 257)->256.
+ * Send an NREAD to address=0x00008 and size=256.
+ * Update the address and size with the returned value->
+ * address+=256->address=0x00108 size-=256->size=1.
+ * Call RIOPACKET_getReadPacketSize(0x00108, 1)->1.
+ * Send an NREAD to address=0x00108 and size=1.
+ * Update the address and size with the returned value->
+ * address+=1->address=0x00109 size-=1->size=0.
+ * All the data has been read.
+ *
+ */
+uint32_t RIOPACKET_getReadPacketSize(uint32_t address, uint32_t size)
+{
+ uint32_t returnValue;
+
+
+ switch(address%8)
+ {
+ case 0:
+ if(size >= 256)
+ {
+ returnValue = 256;
+ }
+ else if(size >= 224)
+ {
+ returnValue = 224;
+ }
+ else if(size >= 192)
+ {
+ returnValue = 192;
+ }
+ else if(size >= 160)
+ {
+ returnValue = 160;
+ }
+ else if(size >= 128)
+ {
+ returnValue = 128;
+ }
+ else if(size >= 96)
+ {
+ returnValue = 96;
+ }
+ else if(size >= 64)
+ {
+ returnValue = 64;
+ }
+ else if(size >= 32)
+ {
+ returnValue = 32;
+ }
+ else if(size >= 16)
+ {
+ returnValue = 16;
+ }
+ else if(size >= 8)
+ {
+ returnValue = 8;
+ }
+ else
+ {
+ returnValue = size;
+ }
+ break;
+ case 1:
+ if(size >= 7)
+ {
+ returnValue = 7;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 2:
+ if(size >= 6)
+ {
+ returnValue = 6;
+ }
+ else if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 3:
+ if(size >= 5)
+ {
+ returnValue = 5;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 4:
+ if(size >= 4)
+ {
+ returnValue = 4;
+ }
+ else if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 5:
+ if(size >= 3)
+ {
+ returnValue = 3;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ case 6:
+ if(size >= 2)
+ {
+ returnValue = 2;
+ }
+ else
+ {
+ returnValue = 1;
+ }
+ break;
+ default:
+ returnValue = 1;
+ break;
+ }
+
+ return returnValue;
+}
+
+
+
+/*******************************************************************************
+ * Locally used helper functions.
+ *******************************************************************************/
+
+static uint16_t getPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, uint8_t *data)
+{
+ uint32_t content = 0;
+ uint16_t packetIndex;
+ uint16_t payloadIndex;
+ uint16_t dataIndex;
+
+
+ /* Move payload bytes from RapidIO packet into a user buffer. */
+ /* Long packets contain a CRC in byte 80-81, this is removed when the buffer
+ is copied. */
+ packetIndex = payloadOffset;
+ payloadIndex = 0;
+ dataIndex = 0;
+ while(dataIndex < dataSize)
+ {
+ /* Check if a new word should be read from the inbound queue. */
+ if((packetIndex & 0x3) == 0)
+ {
+ /* Get a new word. */
+ content = packet[packetIndex>>2];
+ }
+ else
+ {
+ /* Update the current word. Remove the MSB, it has already be moved
+ to the user buffer. */
+ content <<= 8;
+ }
+
+ /* Check if the current byte is CRC. */
+ if((packetIndex != 80) && (packetIndex != 81) && (payloadIndex >= dataOffset))
+ {
+ /* Not CRC. */
+ /* Move the byte to the user buffer. */
+ data[dataIndex++] = (content >> 24);
+ }
+
+ /* Increment to the next position in the packet. */
+ packetIndex++;
+ payloadIndex++;
+ }
+
+ return dataIndex;
+}
+
+
+static uint16_t setPacketPayload(uint32_t *packet, const uint16_t payloadOffset, const uint16_t dataOffset,
+ const uint16_t dataSize, const uint8_t *data)
+{
+ uint16_t crc = 0xffffu;
+ uint32_t content = 0;
+ uint16_t packetIndex;
+ uint16_t payloadIndex;
+ uint16_t dataIndex;
+
+
+ /***************************************************
+ * Calculate the CRC for the packet header.
+ ***************************************************/
+ for(packetIndex = 0; packetIndex < payloadOffset; packetIndex+=4)
+ {
+ crc = RIOPACKET_Crc32(packet[packetIndex>>2], crc);
+ }
+
+ /***************************************************
+ * Pad the data before the actual data is written.
+ ***************************************************/
+ payloadIndex = 0;
+ while(payloadIndex < dataOffset)
+ {
+ content <<= 8;
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = RIOPACKET_Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ payloadIndex++;
+ packetIndex++;
+ }
+
+ /***************************************************
+ * Write content and any embedded CRC.
+ ***************************************************/
+ dataIndex = 0;
+ while(dataIndex < dataSize)
+ {
+ content <<= 8;
+
+ /* Check if CRC or content should be entered into the packet. */
+ if(packetIndex == 80)
+ {
+ /* CRC MSB. */
+ content |= crc >> 8;
+ }
+ else if(packetIndex == 81)
+ {
+ /* CRC LSB. */
+ content |= crc & 0xff;
+ }
+ else
+ {
+ /* Data content. */
+ content |= data[dataIndex++];
+ payloadIndex++;
+ }
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = RIOPACKET_Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ packetIndex++;
+ }
+
+ /***************************************************
+ * Pad the data to an even double word.
+ ***************************************************/
+ while((payloadIndex & 0x7) != 0)
+ {
+ content <<= 8;
+
+ if((packetIndex & 0x3) == 3)
+ {
+ crc = RIOPACKET_Crc32(content, crc);
+ packet[packetIndex>>2] = content;
+ }
+
+ packetIndex++;
+ payloadIndex++;
+ }
+
+ /***************************************************
+ * Write the CRC into the packet.
+ ***************************************************/
+ if((packetIndex & 0x3) == 0)
+ {
+ /* crc(15:0)|pad(15:0) */
+ content = ((uint32_t) crc) << 16;
+ }
+ else
+ {
+ /* double-wordN-LSB|crc(15:0) */
+ content &= 0x0000ffff;
+ crc = RIOPACKET_Crc16(content, crc);
+ content <<= 16;
+ content |= crc;
+ }
+ packet[packetIndex>>2] = content;
+
+ return (packetIndex>>2)+1;
+}
+
+
+
+/* \note See the RapidIO standard part1 table 4-4 for details about
+ * {address, size}->{wdptr, wrsize} mapping.
+ */
+static uint16_t rdsizeGet(const uint32_t address, const uint16_t size)
+{
+ uint8_t wdptr;
+ uint8_t rdsize;
+
+
+ switch(size/8)
+ {
+ case 0:
+ /**************************************************************
+ * Sub double-word access.
+ **************************************************************/
+ switch(size%8)
+ {
+ case 0:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 1:
+ /* Reading one byte. */
+ /* Any address is allowed. */
+ wdptr = (address >> 2) & 0x1;
+ rdsize = address & 0x3;
+ break;
+ case 2:
+ /* Reading two bytes. */
+ /* Address 0, 2, 4, 6 are valid. */
+ if((address & 0x1) == 0)
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = (address & 0x7) | 0x4;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Reading 3 bytes. */
+ /* Address 0 and 5 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 5))
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = 0x5ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 4:
+ /* Reading 4 bytes. */
+ /* Address 0 and 4 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 4))
+ {
+ wdptr = (address >> 2) & 0x1;
+ rdsize = 0x8ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 5:
+ /* Reading 5 bytes. */
+ /* Address 0 and 3 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 3))
+ {
+ wdptr = (address >> 1) & 0x1;
+ rdsize = 0x7ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 6:
+ /* Reading 6 bytes. */
+ /* Addresses 0 and 2 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 2))
+ {
+ wdptr = (address >> 1) & 0x1;
+ rdsize = 0x9ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ default:
+ /* Reading 7 bytes. */
+ /* Addresses 0 and 1 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 1))
+ {
+ wdptr = address & 0x1;
+ rdsize = 0xaul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ }
+ break;
+ case 1:
+ /* Reading 8 bytes. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 2:
+ /* Reading 16 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 4:
+ /* Reading 32 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 5:
+ case 6:
+ case 7:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 8:
+ /* Reading 64 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 9:
+ case 10:
+ case 11:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 12:
+ /* Reading 96 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 13:
+ case 14:
+ case 15:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 16:
+ /* Reading 128 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 17:
+ case 18:
+ case 19:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 20:
+ /* Reading 160 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xeul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 21:
+ case 22:
+ case 23:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 24:
+ /* Reading 192 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xeul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 25:
+ case 26:
+ case 27:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 28:
+ /* Reading 224 bytes. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ rdsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ case 29:
+ case 30:
+ case 31:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ case 32:
+ /* Reading 256 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ rdsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ }
+ break;
+ default:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ rdsize = 0xff;
+ break;
+ }
+
+ return ((((uint16_t) rdsize) << 8) | ((uint16_t) wdptr));
+}
+
+
+void rdsizeToOffset(uint8_t rdsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
+{
+ switch(rdsize)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ *offset = wdptr << 2;
+ *offset |= rdsize;
+ *size = 1;
+ break;
+ case 4:
+ case 6:
+ *offset = wdptr << 2;
+ *offset |= rdsize & 0x02;
+ *size = 2;
+ break;
+ case 5:
+ *offset = wdptr * 5;
+ *size = 3;
+ break;
+ case 8:
+ *offset = wdptr * 4;
+ *size = 4;
+ break;
+ case 7:
+ *offset = wdptr * 3;
+ *size = 5;
+ break;
+ case 9:
+ *offset = wdptr * 2;
+ *size = 6;
+ break;
+ case 10:
+ *offset = wdptr * 1;
+ *size = 7;
+ break;
+ case 11:
+ *offset = 0;
+ *size = 8 + 8*wdptr;
+ break;
+ case 12:
+ *offset = 0;
+ *size = 32 + 32*wdptr;
+ break;
+ case 13:
+ *offset = 0;
+ *size = 96 + 32*wdptr;
+ break;
+ case 14:
+ *offset = 0;
+ *size = 160 + 32*wdptr;
+ break;
+ case 15:
+ *offset = 0;
+ *size = 224 + 32*wdptr;
+ break;
+ }
+}
+
+
+static uint16_t wrsizeGet(const uint32_t address, const uint16_t size)
+{
+ uint8_t wdptr;
+ uint8_t wrsize;
+
+
+ switch(size/8)
+ {
+ case 0:
+ /**************************************************************
+ * Sub double-word access.
+ **************************************************************/
+ switch(size%8)
+ {
+ case 0:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ break;
+ case 1:
+ /* Writing one byte. */
+ /* Any address is allowed. */
+ wdptr = (address >> 2) & 0x1;
+ wrsize = address & 0x3;
+ break;
+ case 2:
+ /* Writing two bytes. */
+ /* Address 0, 2, 4, 6 are valid. */
+ if((address & 0x1) == 0)
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = (address & 0x7) | 0x4;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 3:
+ /* Writing 3 bytes. */
+ /* Address 0 and 5 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 5))
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = 0x5ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 4:
+ /* Writing 4 bytes. */
+ /* Address 0 and 4 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 4))
+ {
+ wdptr = (address >> 2) & 0x1;
+ wrsize = 0x8ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 5:
+ /* Writing 5 bytes. */
+ /* Address 0 and 3 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 3))
+ {
+ wdptr = (address >> 1) & 0x1;
+ wrsize = 0x7ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 6:
+ /* Writing 6 bytes. */
+ /* Addresses 0 and 2 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 2))
+ {
+ wdptr = (address >> 1) & 0x1;
+ wrsize = 0x9ul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ default:
+ /* Writing 7 bytes. */
+ /* Addresses 0 and 1 are valid. */
+ if(((address & 0x7) == 0) ||
+ ((address & 0x7) == 1))
+ {
+ wdptr = address & 0x1;
+ wrsize = 0xaul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ }
+ break;
+ case 1:
+ /* Writing 8 bytes. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 0;
+ wrsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 2:
+ /* Writing 16 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address % 8) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xbul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 3:
+ case 4:
+ /* Writing 32 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 0;
+ wrsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ /* Writing 64 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xcul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ /* Writing 128 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xdul;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ /* Writing 256 bytes max. */
+ /* Only even double-word address are valid. */
+ if((address & 0x7) == 0)
+ {
+ wdptr = 1;
+ wrsize = 0xful;
+ }
+ else
+ {
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ }
+ break;
+ default:
+ /* Not supported by protocol. */
+ wdptr = 0xff;
+ wrsize = 0xff;
+ break;
+ }
+
+ return ((((uint16_t) wrsize) << 8) | ((uint16_t) wdptr));
+}
+
+
+void wrsizeToOffset(uint8_t wrsize, uint8_t wdptr, uint8_t *offset, uint16_t *size)
+{
+ switch(wrsize)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ *offset = wdptr << 2;
+ *offset |= wrsize;
+ *size = 1;
+ break;
+ case 4:
+ case 6:
+ *offset = wdptr << 2;
+ *offset |= wrsize & 0x02;
+ *size = 2;
+ break;
+ case 5:
+ *offset = wdptr * 5;
+ *size = 3;
+ break;
+ case 8:
+ *offset = wdptr * 4;
+ *size = 4;
+ break;
+ case 7:
+ *offset = wdptr * 3;
+ *size = 5;
+ break;
+ case 9:
+ *offset = wdptr * 2;
+ *size = 6;
+ break;
+ case 10:
+ *offset = wdptr * 1;
+ *size = 7;
+ break;
+ case 11:
+ *offset = 0;
+ *size = 8 + 8*wdptr;
+ break;
+ case 12:
+ *offset = 0;
+ *size = 32 + 32*wdptr;
+ break;
+ case 13:
+ *offset = 0;
+ *size = 128*wdptr;
+ break;
+ case 14:
+ *offset = 0;
+ *size = 0;
+ break;
+ case 15:
+ *offset = 0;
+ *size = 256*wdptr;
+ break;
+ }
+}
+
+/*************************** end of file **************************************/
Index: tags/1.0.2-release/sw/stack/rioconfig.h
===================================================================
--- tags/1.0.2-release/sw/stack/rioconfig.h (nonexistent)
+++ tags/1.0.2-release/sw/stack/rioconfig.h (revision 50)
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains the implementation dependent information needed to build
+ * the riostack. Replace declarations and definitions in this file to customize
+ * for your own compiler environment.
+ *
+ * No copyright for this file since it has to be changed.
+ *
+ * To Do:
+ * -
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************/
+
+#ifndef __RIO_CONFIG
+#define __RIO_CONFIG
+
+/*******************************************************************************
+* Includes
+*******************************************************************************/
+
+#include
+
+/*******************************************************************************
+* Global typedefs
+*******************************************************************************/
+
+#ifndef ASSERT
+#ifdef MODULE_TEST
+#include
+#define ASSERT(c, s) (c)?:fprintf(stderr, s)
+#endif
+#endif
+
+#ifndef ASSERT0
+#ifdef MODULE_TEST
+#include
+#define ASSERT0(s) fprintf(stderr, s)
+#endif
+#endif
+
+#ifndef DEBUG_OUT
+#define DEBUG_OUT(...) fprintf(stderr, __VA_ARGS__)
+#endif
+
+/*******************************************************************************
+* Global declarations
+*******************************************************************************/
+
+/*******************************************************************************
+* Global function prototypes
+*******************************************************************************/
+
+#endif // __RIO_CONFIG
+
+/*************************** end of file **************************************/
tags/1.0.2-release/sw/stack/rioconfig.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/sw/stack/riostack.h
===================================================================
--- tags/1.0.2-release/sw/stack/riostack.h (nonexistent)
+++ tags/1.0.2-release/sw/stack/riostack.h (revision 50)
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains the API of the riostack.c module.
+ *
+ * To Do:
+ * -
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************
+ *
+ * Copyright (C) 2015 Authors and OPENCORES.ORG
+ *
+ * This source file may be used and distributed without
+ * restriction provided that this copyright statement is not
+ * removed from the file and that any derivative work contains
+ * the original copyright notice and the associated disclaimer.
+ *
+ * This source file is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This source 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this source; if not, download it
+ * from http://www.opencores.org/lgpl.shtml
+ *
+ *******************************************************************************/
+
+/**
+ * \file riostack.h
+ */
+
+#ifndef _RIOSTACK_H
+#define _RIOSTACK_H
+
+/*******************************************************************************
+ * Includes
+ *******************************************************************************/
+
+#include "rioconfig.h"
+#include "riopacket.h"
+
+
+/*******************************************************************************
+ * Global typedefs
+ *******************************************************************************/
+
+/* The size of a maximum sized RapidIO packet when stored in memory. */
+/* One entry contains a header with the used buffer size. */
+#define RIOSTACK_BUFFER_SIZE (RIOPACKET_SIZE_MAX+1u)
+
+
+/* Define the different types of RioSymbols. */
+typedef enum
+ {
+ RIOSTACK_SYMBOL_TYPE_IDLE, RIOSTACK_SYMBOL_TYPE_CONTROL,
+ RIOSTACK_SYMBOL_TYPE_DATA, RIOSTACK_SYMBOL_TYPE_ERROR
+ } RioSymbolType_t;
+
+
+/*
+ * RapidIO symbol definition.
+ * Idle symbol: Sent when nothing else to send. Does not use the data field.
+ * Control symbol: Sent when starting, ending and acknowleding a packet. Data
+ * is right aligned, (Unused, C0, C1, C2) where C0 is transmitted/received first.
+ * Data symbol: Sent to transfer packets. Uses the full data field, (D0, D1,
+ * D2, D3) where D0 is transmitted/received first.
+ * Error symbols are created when a symbols could not be created and the stack
+ * should know about it.
+ */
+typedef struct
+{
+ RioSymbolType_t type;
+ uint32_t data;
+} RioSymbol_t;
+
+
+/* Receiver states. */
+typedef enum
+ {
+ RX_STATE_UNINITIALIZED, RX_STATE_PORT_INITIALIZED, RX_STATE_LINK_INITIALIZED,
+ RX_STATE_INPUT_RETRY_STOPPED, RX_STATE_INPUT_ERROR_STOPPED
+ } RioReceiverState_t;
+
+
+/* Transmitter states. */
+typedef enum
+ {
+ TX_STATE_UNINITIALIZED, TX_STATE_PORT_INITIALIZED, TX_STATE_LINK_INITIALIZED,
+ TX_STATE_SEND_PACKET_RETRY, TX_STATE_SEND_PACKET_NOT_ACCEPTED, TX_STATE_SEND_LINK_RESPONSE,
+ TX_STATE_OUTPUT_RETRY_STOPPED, TX_STATE_OUTPUT_ERROR_STOPPED
+ } RioTransmitterState_t;
+
+
+/* Queue definition. */
+typedef struct
+{
+ uint8_t size;
+ uint8_t available;
+ uint8_t windowSize;
+ uint8_t windowIndex;
+ uint8_t frontIndex;
+ uint8_t backIndex;
+ uint32_t *buffer_p;
+} Queue_t;
+
+
+
+/* Define the structure to keep all the RapidIO stack variables. */
+typedef struct
+{
+ /* Receiver variables. */
+ RioReceiverState_t rxState;
+ uint8_t rxCounter;
+ uint16_t rxCrc;
+ uint8_t rxStatusReceived;
+ uint8_t rxAckId;
+ uint8_t rxAckIdAcked;
+ uint8_t rxErrorCause;
+ Queue_t rxQueue;
+
+ /* Transmitter variables. */
+ RioTransmitterState_t txState;
+ uint8_t txCounter;
+ uint16_t txStatusCounter;
+ uint8_t txFrameState;
+ uint32_t txFrameTimeout[32];
+ uint8_t txAckId;
+ uint8_t txAckIdWindow;
+ uint8_t txBufferStatus;
+ Queue_t txQueue;
+
+ /* Common protocol stack variables. */
+ uint32_t portTime;
+ uint32_t portTimeout;
+
+ /** The number of successfully received packets. */
+ uint32_t statusInboundPacketComplete;
+
+ /** The number of retried received packets.
+ This will happen if the receiver does not have resources available when an inbound packet is received. */
+ uint32_t statusInboundPacketRetry;
+
+ /** The number of received erronous control symbols.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorControlCrc;
+
+ /** The number of received packets with an unexpected ackId.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorPacketAckId;
+
+ /** The number of received packets with a checksum error.
+ This may happen if the inbound link has a high bit-error-rate. */
+ uint32_t statusInboundErrorPacketCrc;
+
+ /** The number of received symbols that contains an illegals character.
+ This may happen if the inbound link has a high bit-error-rate or if characters are missing in the
+ inbound character stream. */
+ uint32_t statusInboundErrorIllegalCharacter;
+
+ /** The number of general errors encountered at the receiver that does not fit into the other categories.
+ This happens if too short or too long packets are received. */
+ uint32_t statusInboundErrorGeneral;
+
+ /** The number of received packets that were discarded since they were unsupported by the stack.
+ This will happen if an inbound packet contains information that cannot be accessed using the function API
+ of the stack. */
+ uint32_t statusInboundErrorPacketUnsupported;
+
+ /** The number of successfully transmitted packets. */
+ uint32_t statusOutboundPacketComplete;
+
+ /** The maximum time between a completed outbound packet and the reception of its pcakcet-accepted control-symbol. */
+ uint32_t statusOutboundLinkLatencyMax;
+
+ /** The number of retried transmitted packets.
+ This will happen if the receiver at the link-partner does not have resources available when an outbound
+ packet is received. */
+ uint32_t statusOutboundPacketRetry;
+
+ /** The number of outbound packets that has had its retransmission timer expired.
+ This happens if the latency of the system is too high or if a packet is corrupted due to a high
+ bit-error-rate on the outbound link. */
+ uint32_t statusOutboundErrorTimeout;
+
+ /** The number of packet-accepted that was received that contained an unexpected ackId.
+ This happens if the transmitter and the link-partner is out of synchronization, probably due
+ to a software error. */
+ uint32_t statusOutboundErrorPacketAccepted;
+
+ /** The number of packet-retry that was received that contained an unexpected ackId.
+ This happens if the transmitter and the link-partner is out of synchronization, probably due to
+ a software error. */
+ uint32_t statusOutboundErrorPacketRetry;
+
+ /** The number of received link-requests.
+ This happens if the link-partner transmitter has found an error and need to resynchronize itself
+ to the receiver. */
+ uint32_t statusPartnerLinkRequest;
+
+ /** The number of received erronous control symbols at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorControlCrc;
+
+ /** The number of received packets with an unexpected ackId at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorPacketAckId;
+
+ /** The number of received packets with a checksum error at the link-partner receiver.
+ This may happen if the outbound link has a high bit-error-rate. */
+ uint32_t statusPartnerErrorPacketCrc;
+
+ /** The number of received symbols that contains an illegals character at the link-parter receiver.
+ This may happen if the outbound link has a high bit-error-rate or if characters are missing in the
+ outbound character stream. */
+ uint32_t statusPartnerErrorIllegalCharacter;
+
+ /** The number of general errors encountered at the receiver that does not fit into the other categories.
+ This happens depending on the link-partner implementation. */
+ uint32_t statusPartnerErrorGeneral;
+
+ /* Private user data. */
+ void* private;
+} RioStack_t;
+
+
+/*******************************************************************************
+ * Global function prototypes
+ *******************************************************************************/
+
+/**
+ * \brief Open the RapidIO stack for operation.
+ *
+ * \param[in] stack Stack instance to operate on.
+ * \param[in] private Pointer to an opaque data area containing private user data.
+ * \param[in] rxPacketBufferSize Number of words to use as reception buffer. This
+ * argument specifies the size of rxPacketBuffer.
+ * \param[in] rxPacketBuffer Pointer to buffer to store inbound packets in.
+ * \param[in] txPacketBufferSize Number of words to use as transmission buffer. This
+ * argument specifies the size of txPacketBuffer.
+ * \param[in] txPacketBuffer Pointer to buffer to store outbound packets in.
+ *
+ * This function initializes all internally used variables in the stack. The stack will
+ * however not be operational until the transcoder has signalled that it is ready for
+ * other symbols than idle. This is done using the function RIOSTACK_setPortStatus(). Once
+ * this function has been called it is possible to get and set symbols and to issue
+ * requests. The requests will be transmitted once the link initialization has
+ * been completed.
+ *
+ * The rxPacket/txPacket arguments are word buffers that are used internally to store the
+ * inbound and outbound packet queues.
+ *
+ * The config argument constants are used as identification when maintenance packets
+ * are received and replied to. They should be set to make the device where the stack
+ * is used easily identifiable on the net.
+ *
+ * \note The reception buffers can only support maximum 31 buffers.
+ */
+void RIOSTACK_open(RioStack_t *stack, void *private,
+ const uint32_t rxPacketBufferSize, uint32_t *rxPacketBuffer,
+ const uint32_t txPacketBufferSize, uint32_t *txPacketBuffer);
+
+/*******************************************************************************************
+ * Stack status functions.
+ * Note that status counters are access directly in the stack-structure.
+ *******************************************************************************************/
+
+/**
+ * \brief Get the status of the link.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the status of the link, zero if link is uninitialized and non-zero if
+ * the link is initialized.
+ *
+ * This function indicates if the link is up and ready to relay packets.
+ */
+int RIOSTACK_getStatus(RioStack_t *stack);
+
+/**
+ * \brief Clear outbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ *
+ * This function clears all pending packet in the outbound queue.
+ */
+void RIOSTACK_clearOutboundQueue(RioStack_t *stack);
+
+/**
+ * \brief Get the number of pending outbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of pending outbound packets.
+ *
+ * This function checks the outbound queue and returns the number of packets
+ * that are pending to be transmitted onto the link.
+ */
+uint8_t RIOSTACK_getOutboundQueueLength(RioStack_t *stack);
+
+/**
+ * \brief Get the number of available outbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of available outbound packets.
+ *
+ * This function checks the outbound queue and returns the number of packets
+ * that are available before the queue is full.
+ */
+uint8_t RIOSTACK_getOutboundQueueAvailable(RioStack_t *stack);
+
+/**
+ * \brief Add a packet to the outbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] packet The packet to send.
+ *
+ * This function sends a packet.
+ *
+ * \note The packet CRC is not checked. It must have been checked before it is used as
+ * argument to this function.
+ *
+ * \note Call RIOSTACK_outboundQueueAvailable() before this function is called to make sure
+ * the outbound queue has transmission buffers available.
+ *
+ * \note Use RIOSTACK_getStatus() to know when a packet is allowed to be transmitted.
+ */
+void RIOSTACK_setOutboundPacket(RioStack_t *stack, RioPacket_t *packet);
+
+/**
+ * \brief Clear inbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ *
+ * This function clears all pending packet in the inbound queue.
+ */
+void RIOSTACK_clearInboundQueue(RioStack_t *stack);
+
+/**
+ * \brief Get the number of pending inbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of pending inbound packets.
+ *
+ * This function checks the inbound queue and returns the number of packets
+ * that has been received but not read by the user yet.
+ */
+uint8_t RIOSTACK_getInboundQueueLength(RioStack_t *stack);
+
+/**
+ * \brief Get the number of available inbound packets.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return Returns the number of available inbound packets.
+ *
+ * This function checks the inbound queue and returns the number of packets
+ * that can be received without the queue is full.
+ */
+uint8_t RIOSTACK_getInboundQueueAvailable(RioStack_t *stack);
+
+/**
+ * \brief Get, remove and return a packet from the inbound queue.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] packet The packet to receive to.
+ *
+ * This function moves a packet from the inbound packet queue to the location of the packet
+ * in the argument list.
+ */
+void RIOSTACK_getInboundPacket(RioStack_t *stack, RioPacket_t *packet);
+
+/*******************************************************************************************
+ * Port functions (backend API towards physical device)
+ *******************************************************************************************/
+
+/**
+ * \brief Set a port current time.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] time The current time without unit.
+ *
+ * This function indicates to the stack the current time and this is used internally
+ * to calculate when a packet timeout should be triggered. Use this together with RIOSTACK_setPortTimeout()
+ * to allow for the stack to handle timeouts.
+ */
+void RIOSTACK_portSetTime( RioStack_t *stack, const uint32_t time);
+
+/**
+ * \brief Set a port timeout limit.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] time The time out threshold.
+ *
+ * The time to wait for a response from the link partner. The unit of the
+ * timeout value should be the same as the time used in RIOSTACK_setPortTime().
+ *
+ * This function is used to set a timeout threshold value and is used to know when
+ * an acknowledge should have been received from a link partner.
+ */
+void RIOSTACK_portSetTimeout( RioStack_t *stack, const uint32_t time);
+
+/**
+ * \brief Set a ports status.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] initialized The state of the port.
+ *
+ * If set to non-zero, the symbol encoder/decoder indicates to the stack that
+ * it is successfully encoding/decoding symbol, i.e. synchronized to the link.
+ *
+ * This function indicates to the stack if the port that are encoding/decoding
+ * symbols are ready to accept other symbols than idle-symbols. If the
+ * encoding/decoding loses synchronization then this function should be called
+ * with an argument equal to zero to force the stack to resynchronize the link.
+ */
+void RIOSTACK_portSetStatus( RioStack_t *stack, const uint8_t initialized );
+
+/**
+ * \brief Add a new symbol to the RapidIO stack.
+ *
+ * \param[in] stack The stack to operate on.
+ * \param[in] s A symbol received from a port.
+ *
+ * This function is used to insert new data, read from a port, into the stack. The
+ * symbols will be concatenated to form packets that can be accessed using other
+ * functions.
+ */
+void RIOSTACK_portAddSymbol( RioStack_t *stack, const RioSymbol_t s );
+
+/**
+ * \brief Get the next symbol to transmit on a port.
+ *
+ * \param[in] stack The stack to operate on.
+ * \return A symbol that should be sent on a port.
+ *
+ * This function is used to fetch new symbols to transmit on a port. Packets that
+ * are inserted are split into symbols that are accessed with this function.
+ */
+RioSymbol_t RIOSTACK_portGetSymbol( RioStack_t *stack );
+
+#endif /* _RIOSTACK_H */
+
+/*************************** end of file **************************************/
tags/1.0.2-release/sw/stack/riostack.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/sw/stack/riopacket.h
===================================================================
--- tags/1.0.2-release/sw/stack/riopacket.h (nonexistent)
+++ tags/1.0.2-release/sw/stack/riopacket.h (revision 50)
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains the public API for riopacket.
+ *
+ * To Do:
+ * -
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************
+ *
+ * Copyright (C) 2015 Authors and OPENCORES.ORG
+ *
+ * This source file may be used and distributed without
+ * restriction provided that this copyright statement is not
+ * removed from the file and that any derivative work contains
+ * the original copyright notice and the associated disclaimer.
+ *
+ * This source file is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This source 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this source; if not, download it
+ * from http://www.opencores.org/lgpl.shtml
+ *
+ *******************************************************************************/
+
+/**
+ * \file riopacket.c
+ */
+
+#ifndef __RIOPACKET_H
+#define __RIOPACKET_H
+
+/*******************************************************************************
+ * Includes
+ *******************************************************************************/
+
+#include "rioconfig.h"
+
+
+/*******************************************************************************
+ * Global typedefs
+ *******************************************************************************/
+
+/* The maximum size of a RapidIO packet in words (32-bit). */
+#define RIOPACKET_SIZE_MIN 3u
+#define RIOPACKET_SIZE_MAX 69u
+
+/* Configuration space offsets. */
+#define DEVICE_IDENTITY_CAR ((uint32_t)0x00000000ul)
+#define DEVICE_INFORMATION_CAR ((uint32_t)0x00000004ul)
+#define ASSEMBLY_IDENTITY_CAR ((uint32_t)0x00000008ul)
+#define ASSEMBLY_INFORMATION_CAR ((uint32_t)0x0000000cul)
+#define PROCESSING_ELEMENT_FEATURES_CAR ((uint32_t)0x00000010ul)
+#define SWITCH_PORT_INFORMATION_CAR ((uint32_t)0x00000014ul)
+#define SOURCE_OPERATIONS_CAR ((uint32_t)0x00000018ul)
+#define DESTINATION_OPERATIONS_CAR ((uint32_t)0x0000001cul)
+#define SWITCH_ROUTE_TABLE_DESTINATION_ID_LIMIT_CAR ((uint32_t)0x00000034ul)
+#define PROCESSING_ELEMENT_LOGICAL_LAYER_CONTROL_CSR ((uint32_t)0x0000004cul)
+#define BASE_DEVICE_ID_CSR ((uint32_t)0x00000060ul)
+#define HOST_BASE_DEVICE_ID_LOCK_CSR ((uint32_t)0x00000068ul)
+#define COMPONENT_TAG_CSR ((uint32_t)0x0000006cul)
+#define STANDARD_ROUTE_CONFIGURATION_DESTINATION_ID_SELECT_CSR ((uint32_t)0x00000070ul)
+#define STANDARD_ROUTE_CONFIGURATION_PORT_SELECT_CSR ((uint32_t)0x00000074ul)
+#define STANDARD_ROUTE_DEFAULT_PORT_CSR ((uint32_t)0x00000078ul)
+#define EXTENDED_FEATURES_OFFSET ((uint32_t)0x00000100ul)
+#define IMPLEMENTATION_DEFINED_OFFSET ((uint32_t)0x00010000ul)
+#define LP_SERIAL_REGISTER_BLOCK_HEADER(offset) (offset)
+#define PORT_LINK_TIMEOUT_CONTROL_CSR(offset) ((offset) + 0x00000020ul)
+#define PORT_RESPONSE_TIMEOUT_CONTROL_CSR(offset) ((offset) + 0x00000024ul)
+#define PORT_GENERAL_CONTROL_CSR(offset) ((offset) + 0x0000003cul)
+#define PORT_N_LOCAL_ACKID_CSR(offset, n) ((offset) + (0x00000048ul+((n)*0x00000020ul)))
+#define PORT_N_ERROR_AND_STATUS_CSR(offset, n) ((offset) + (0x00000058ul+((n)*0x00000020ul)))
+#define PORT_N_CONTROL_CSR(offset, n) ((offset) + (0x0000005cul+((n)*0x00000020ul)))
+
+/* Packet ftype constants. */
+#define RIOPACKET_FTYPE_REQUEST 0x2
+#define RIOPACKET_FTYPE_WRITE 0x5
+#define RIOPACKET_FTYPE_MAINTENANCE 0x8
+#define RIOPACKET_FTYPE_DOORBELL 0xa
+#define RIOPACKET_FTYPE_MESSAGE 0xb
+#define RIOPACKET_FTYPE_RESPONSE 0xd
+
+/* Transaction constants. */
+#define RIOPACKET_TRANSACTION_MAINT_READ_REQUEST 0ul
+#define RIOPACKET_TRANSACTION_MAINT_WRITE_REQUEST 1ul
+#define RIOPACKET_TRANSACTION_MAINT_READ_RESPONSE 2ul
+#define RIOPACKET_TRANSACTION_MAINT_WRITE_RESPONSE 3ul
+#define RIOPACKET_TRANSACTION_MAINT_PORT_WRITE_REQUEST 4ul
+#define RIOPACKET_TRANSACTION_WRITE_NWRITE 4ul
+#define RIOPACKET_TRANSACTION_WRITE_NWRITER 5ul
+#define RIOPACKET_TRANSACTION_REQUEST_NREAD 4ul
+#define RIOPACKET_TRANSACTION_RESPONSE_NO_PAYLOAD 0ul
+#define RIOPACKET_TRANSACTION_RESPONSE_MESSAGE_RESPONSE 1ul
+#define RIOPACKET_TRANSACTION_RESPONSE_WITH_PAYLOAD 8ul
+
+/* Response status constants. */
+#define RIOPACKET_RESPONSE_STATUS_DONE 0ul
+#define RIOPACKET_RESPONSE_STATUS_RETRY 3ul
+#define RIOPACKET_RESPONSE_STATUS_ERROR 7ul
+
+
+/* The structure containing a RapidIO packet. */
+typedef struct
+{
+ /* Size in words. */
+ uint8_t size;
+ uint32_t payload[RIOPACKET_SIZE_MAX];
+} RioPacket_t;
+
+
+
+/*******************************************************************************
+ * Global function prototypes
+ *******************************************************************************/
+
+void RIOPACKET_init(RioPacket_t *packet);
+uint8_t RIOPACKET_size(RioPacket_t *packet);
+void RIOPACKET_append(RioPacket_t *packet, uint32_t word);
+
+int RIOPACKET_valid(RioPacket_t *packet);
+
+int RIOPACKET_serialize(RioPacket_t *packet, const uint16_t size, uint8_t *buffer);
+int RIOPACKET_deserialize(RioPacket_t *packet, const uint16_t size, const uint8_t *buffer);
+
+#ifdef ENABLE_TOSTRING
+#include
+void RIOPACKET_toString(RioPacket_t *packet, char *buffer);
+#endif
+
+uint8_t RIOPACKET_getFtype(RioPacket_t *packet);
+uint16_t RIOPACKET_getDestination(RioPacket_t *packet);
+uint16_t RIOPACKET_getSource(RioPacket_t *packet);
+uint8_t RIOPACKET_getTransaction(RioPacket_t *packet);
+uint8_t RIOPACKET_getTid(RioPacket_t *packet);
+
+void RIOPACKET_setMaintReadRequest(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId, uint8_t hop,
+ uint8_t tid, uint32_t offset);
+void RIOPACKET_getMaintReadRequest(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId, uint8_t *hop,
+ uint8_t *tid, uint32_t *offset);
+
+void RIOPACKET_setMaintReadResponse(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint32_t data);
+void RIOPACKET_getMaintReadResponse(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint32_t *data);
+
+void RIOPACKET_setMaintWriteRequest(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId, uint8_t hop,
+ uint8_t tid, uint32_t offset, uint32_t data);
+void RIOPACKET_getMaintWriteRequest(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId, uint8_t *hop,
+ uint8_t *tid, uint32_t *offset, uint32_t *data);
+
+void RIOPACKET_setMaintWriteResponse(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid);
+void RIOPACKET_getMaintWriteResponse(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid);
+
+void RIOPACKET_setMaintPortWrite(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint32_t componentTag, uint32_t portErrorDetect,
+ uint32_t implementationSpecific, uint8_t portId,
+ uint32_t logicalTransportErrorDetect);
+void RIOPACKET_getMaintPortWrite(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint32_t *componentTag, uint32_t *portErrorDetect,
+ uint32_t *implementationSpecific, uint8_t *portId,
+ uint32_t *logicalTransportErrorDetect);
+
+void RIOPACKET_setNwrite(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint32_t address, uint16_t payloadSize, uint8_t *payload);
+void RIOPACKET_getNwrite(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint32_t *address, uint16_t *payloadSize, uint8_t *payload);
+
+void RIOPACKET_setNwriteR(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid,
+ uint32_t address, uint16_t payloadSize, uint8_t *payload);
+void RIOPACKET_getNwriteR(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid,
+ uint32_t *address, uint16_t *payloadSize, uint8_t *payload);
+
+void RIOPACKET_setNread(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid,
+ uint32_t address, uint16_t payloadSize);
+void RIOPACKET_getNread(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid,
+ uint32_t *address, uint16_t *payloadSize);
+
+
+void RIOPACKET_setDoorbell(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint16_t info);
+void RIOPACKET_getDoorbell(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint16_t *info);
+
+void RIOPACKET_setMessage(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t mailbox,
+ uint16_t size, uint8_t *payload);
+void RIOPACKET_getMessage(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *mailbox,
+ uint16_t *size, uint8_t *payload);
+
+
+void RIOPACKET_setResponseNoPayload(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint8_t status);
+void RIOPACKET_getResponseNoPayload(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint8_t *status);
+
+void RIOPACKET_setResponseWithPayload(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t tid, uint8_t offset,
+ uint16_t size, uint8_t *payload);
+void RIOPACKET_getResponseWithPayload(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *tid, uint8_t offset,
+ uint16_t *size, uint8_t *payload);
+
+void RIOPACKET_setResponseMessage(RioPacket_t *packet,
+ uint16_t destId, uint16_t srcId,
+ uint8_t mailbox, uint8_t status);
+void RIOPACKET_getResponseMessage(RioPacket_t *packet,
+ uint16_t *destId, uint16_t *srcId,
+ uint8_t *mailbox, uint8_t *status);
+
+uint16_t RIOPACKET_Crc16( const uint16_t data, const uint16_t crc);
+uint16_t RIOPACKET_Crc32( const uint32_t data, uint16_t crc);
+
+uint32_t RIOPACKET_getReadPacketSize(uint32_t address, uint32_t size);
+uint32_t RIOPACKET_getWritePacketSize(uint32_t address, uint32_t size);
+
+#endif
+
+/*************************** end of file **************************************/
Index: tags/1.0.2-release/sw/codec/riocodecuart.c
===================================================================
--- tags/1.0.2-release/sw/codec/riocodecuart.c (nonexistent)
+++ tags/1.0.2-release/sw/codec/riocodecuart.c (revision 50)
@@ -0,0 +1,548 @@
+/*******************************************************************************
+ *
+ * RapidIO IP Library Core
+ *
+ * This file is part of the RapidIO IP library project
+ * http://www.opencores.org/cores/rio/
+ *
+ * Description:
+ * This file contains code that can serialize and deserialize rio symbols onto
+ * and from an 8-bit UART transmission channel.
+ *
+ * To Do:
+ * -
+ *
+ * Author(s):
+ * - Magnus Rosenius, magro732@opencores.org
+ *
+ *******************************************************************************
+ *
+ * Copyright (C) 2013 Authors and OPENCORES.ORG
+ *
+ * This source file may be used and distributed without
+ * restriction provided that this copyright statement is not
+ * removed from the file and that any derivative work contains
+ * the original copyright notice and the associated disclaimer.
+ *
+ * This source file is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation;
+ * either version 2.1 of the License, or (at your option) any
+ * later version.
+ *
+ * This source 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 Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this source; if not, download it
+ * from http://www.opencores.org/lgpl.shtml
+ *
+ *******************************************************************************/
+
+#include
+
+typedef enum
+{
+ RIO_SYMBOL_TYPE_IDLE, RIO_SYMBOL_TYPE_CONTROL,
+ RIO_SYMBOL_TYPE_DATA, RIO_SYMBOL_TYPE_ERROR
+} RioSymbolType;
+
+typedef struct
+{
+ RioSymbolType type;
+ uint32_t data;
+} RioSymbol;
+
+typedef struct
+{
+
+} RioStack_t;
+
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s );
+RioSymbol RIO_portGetSymbol( RioStack_t *stack );
+
+
+void receiveByte(RioStack_t *stack, uint8_t incoming)
+{
+ static RioSymbol rxSymbol;
+ static uint8_t flagFound = 0;
+ static uint8_t symbolCounter = 0;
+
+
+ if(incoming != 0x7e)
+ {
+ if(incoming != 0x7d)
+ {
+ if(flagFound)
+ {
+ incoming ^= 0x20;
+ }
+ else
+ {
+ /* Dont do anything. */
+ }
+
+ switch(symbolCounter)
+ {
+ case 0:
+ rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
+ rxSymbol.data = incoming;
+ symbolCounter++;
+ break;
+ case 1:
+ rxSymbol.type = RIO_SYMBOL_TYPE_ERROR;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+ symbolCounter++;
+ break;
+ case 2:
+ rxSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+ symbolCounter++;
+ break;
+ case 3:
+ rxSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ rxSymbol.data <<= 8;
+ rxSymbol.data |= incoming;
+
+ RIO_portAddSymbol(stack, rxSymbol);
+
+ rxSymbol.data = 0x00000000;
+ symbolCounter = 0;
+ break;
+ }
+
+ flagFound = 0;
+ }
+ else
+ {
+ flagFound = 1;
+ }
+ }
+ else
+ {
+ if(symbolCounter == 0)
+ {
+ rxSymbol.type = RIO_SYMBOL_TYPE_IDLE;
+ RIO_portAddSymbol(stack, rxSymbol);
+ }
+ else
+ {
+ RIO_portAddSymbol(stack, rxSymbol);
+ }
+
+ symbolCounter = 0;
+ }
+}
+
+uint8_t transmitByte(RioStack_t *stack)
+{
+ uint8_t returnValue;
+ static uint8_t symbolCounter = 3;
+ static uint8_t stuffing = 0;
+ static RioSymbol txSymbol;
+ uint8_t outbound;
+
+
+ /* Check if the previous symbol has been sent. */
+ if((symbolCounter == 3) && (stuffing == 0))
+ {
+ /* Symbol sent. */
+
+ /* Get a new symbol. */
+ txSymbol = RIO_portGetSymbol(stack);
+ if(txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)
+ {
+ txSymbol.data <<= 8;
+ }
+ }
+ else
+ {
+ /* Symbol not sent. */
+ /* Continue to send the old symbol. */
+ }
+
+ /* Check if a flag should be sent. */
+ if ((txSymbol.type == RIO_SYMBOL_TYPE_IDLE) ||
+ ((stuffing == 0) && (symbolCounter == 0) && (txSymbol.type == RIO_SYMBOL_TYPE_CONTROL)))
+ {
+ /* A flag needs to be sent. */
+ /* An idle symbol should be sent as a flag and a control symbol should always be
+ terminated by a flag. */
+ returnValue = 0x7e;
+ symbolCounter = 3;
+ stuffing = 0;
+ }
+ else
+ {
+ /* A flag does not need to be sent. */
+
+ /* Get the current byte in the symbol. */
+ outbound = txSymbol.data >> (8*symbolCounter);
+
+ /* Check if stuffing is active. */
+ if(!stuffing)
+ {
+ /* No stuffing active. */
+
+ /* Check if the current byte needs to be stuffed. */
+ if((outbound != 0x7e) && (outbound != 0x7d))
+ {
+ /* The current byte does not need to be stuffed. */
+ returnValue = outbound;
+ symbolCounter = (symbolCounter - 1) & 0x3;
+ }
+ else
+ {
+ /* The current byte needs to be stuffed. */
+ returnValue = 0x7d;
+ stuffing = 1;
+ }
+ }
+ else
+ {
+ /* Stuffing is active. */
+ /* An escape sequence has been sent, transmit the original data but change it to not being a flag. */
+ returnValue = outbound ^ 0x20;
+ stuffing = 0;
+ symbolCounter = (symbolCounter - 1) & 0x3;
+ }
+ }
+
+ return returnValue;
+}
+
+
+
+/*******************************************************************************
+ * Module test code.
+ *******************************************************************************/
+
+#define TESTEXPR(got, expected) \
+ if ((got)!=(expected)) \
+ { \
+ printf("ERROR at line %u:%s=%u (0x%08x) expected=%u (0x%08x)\n", \
+ __LINE__, #got, (got), (got), (expected), (expected)); \
+ exit(1); \
+ }
+static RioSymbol txSymbol;
+static uint8_t txNewSymbol;
+static RioSymbol rxSymbol;
+static uint8_t rxNewSymbol;
+void RIO_portAddSymbol( RioStack_t *stack, const RioSymbol s )
+{
+ rxNewSymbol = 1;
+ rxSymbol = s;
+}
+RioSymbol RIO_portGetSymbol( RioStack_t *stack )
+{
+ if(txNewSymbol)
+ {
+ txNewSymbol = 0;
+ return txSymbol;
+ }
+ else
+ {
+ RioSymbol s;
+ s.type = RIO_SYMBOL_TYPE_ERROR;
+ return s;
+ }
+}
+int main(int argc, char *argv[])
+{
+ RioStack_t *stack;
+
+ /***************************************************************
+ * Test receiver.
+ ***************************************************************/
+
+ /* Receive a flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_IDLE);
+
+ /* Receive not a flag followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
+
+ /* Receive not a flag twice followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0x55);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_ERROR);
+
+ /* Receive a control symbol followed by flag. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x11);
+ receiveByte(stack, 0x22);
+ receiveByte(stack, 0x33);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x00112233);
+
+ /* Receive a data symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x44);
+ receiveByte(stack, 0x55);
+ receiveByte(stack, 0x66);
+ receiveByte(stack, 0x77);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x44556677);
+
+ /* Receive a back-to-back data symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x88);
+ receiveByte(stack, 0x99);
+ receiveByte(stack, 0xaa);
+ receiveByte(stack, 0xbb);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x8899aabb);
+
+ /* Receive a back-to-back control symbol. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0xcc);
+ receiveByte(stack, 0xdd);
+ receiveByte(stack, 0xee);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x00ccddee);
+
+ /* Test control symbol with one stuffed byte. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0xff);
+ receiveByte(stack, 0x01);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007eff01);
+
+ /* Test control symbol with two stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0xff);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007eff7d);
+
+ /* Test control symbol with three stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7e);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_CONTROL);
+ TESTEXPR(rxSymbol.data, 0x007d7e7d);
+
+ /* Test data symbol with one stuffed byte. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x00);
+ receiveByte(stack, 0x01);
+ receiveByte(stack, 0x02);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e000102);
+
+ /* Test data symbol with two stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x03);
+ receiveByte(stack, 0x04);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d0304);
+
+ /* Test data symbol with three stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x05);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d7e05);
+
+ /* Test data symbol with four stuffed bytes. */
+ rxNewSymbol = 0;
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5e);
+ receiveByte(stack, 0x7d);
+ receiveByte(stack, 0x5d);
+ TESTEXPR(rxNewSymbol, 1);
+ TESTEXPR(rxSymbol.type, RIO_SYMBOL_TYPE_DATA);
+ TESTEXPR(rxSymbol.data, 0x7e7d7e7d);
+
+ /***************************************************************
+ * Test transmitter.
+ ***************************************************************/
+
+ /* Test transmission of idle symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_IDLE;
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0x00112233;
+ TESTEXPR(transmitByte(stack), 0x11);
+ TESTEXPR(transmitByte(stack), 0x22);
+ TESTEXPR(transmitByte(stack), 0x33);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of data symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x44556677;
+ TESTEXPR(transmitByte(stack), 0x44);
+ TESTEXPR(transmitByte(stack), 0x55);
+ TESTEXPR(transmitByte(stack), 0x66);
+ TESTEXPR(transmitByte(stack), 0x77);
+
+ /* Test transmission of back-to-back data symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x8899aabb;
+ TESTEXPR(transmitByte(stack), 0x88);
+ TESTEXPR(transmitByte(stack), 0x99);
+ TESTEXPR(transmitByte(stack), 0xaa);
+ TESTEXPR(transmitByte(stack), 0xbb);
+
+ /* Test transmission of back-to-back control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xffccddee;
+ TESTEXPR(transmitByte(stack), 0xcc);
+ TESTEXPR(transmitByte(stack), 0xdd);
+ TESTEXPR(transmitByte(stack), 0xee);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of back-to-back control symbol. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff010203;
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x03);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of control symbol with one stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e0102;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of stuffed control symbol with two stuffed bytes. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e7d01;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of stuffed control symbol with three stuffed bytes. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_CONTROL;
+ txSymbol.data = 0xff7e7d7e;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7e);
+
+ /* Test transmission of data symbol with one stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e010203;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+ TESTEXPR(transmitByte(stack), 0x03);
+
+ /* Test transmission of data symbol with two stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d0102;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x01);
+ TESTEXPR(transmitByte(stack), 0x02);
+
+ /* Test transmission of data symbol with three stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d7e01;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x01);
+
+ /* Test transmission of data symbol with four stuffed byte. */
+ txNewSymbol = 1;
+ txSymbol.type = RIO_SYMBOL_TYPE_DATA;
+ txSymbol.data = 0x7e7d7e7d;
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5e);
+ TESTEXPR(transmitByte(stack), 0x7d);
+ TESTEXPR(transmitByte(stack), 0x5d);
+
+ /***************************************************************
+ * Test complete.
+ ***************************************************************/
+
+ printf("Test complete.\n");
+}
tags/1.0.2-release/sw/codec/riocodecuart.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/bench/vhdl/TestRioSwitch.vhd
===================================================================
--- tags/1.0.2-release/bench/vhdl/TestRioSwitch.vhd (nonexistent)
+++ tags/1.0.2-release/bench/vhdl/TestRioSwitch.vhd (revision 50)
@@ -0,0 +1,1266 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains automatic simulation test code to verify a RioSwitch implementation.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- TestRioSwitch.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioSwitch.
+-------------------------------------------------------------------------------
+entity TestRioSwitch is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestRioSwitch.
+-------------------------------------------------------------------------------
+architecture TestRioSwitchImpl of TestRioSwitch is
+
+ component RioSwitch is
+ generic(
+ SWITCH_PORTS : natural range 3 to 255 := 4;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0);
+ writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0);
+
+ readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readContentData_i : in Array32(SWITCH_PORTS-1 downto 0);
+
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component TestPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic;
+ frameWrite_i : in RioFrame;
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ constant PORTS : natural := 7;
+ constant SWITCH_IDENTITY : std_logic_vector(15 downto 0) := x"0123";
+ constant SWITCH_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"4567";
+ constant SWITCH_REV : std_logic_vector(31 downto 0) := x"89abcdef";
+ constant SWITCH_ASSY_IDENTITY : std_logic_vector(15 downto 0) := x"0011";
+ constant SWITCH_ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"2233";
+ constant SWITCH_ASSY_REV : std_logic_vector(15 downto 0) := x"4455";
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal frameValid : Array1(PORTS-1 downto 0);
+ signal frameWrite : RioFrameArray(PORTS-1 downto 0);
+ signal frameComplete : Array1(PORTS-1 downto 0);
+
+ signal frameExpected : Array1(PORTS-1 downto 0);
+ signal frameRead : RioFrameArray(PORTS-1 downto 0);
+ signal frameReceived : Array1(PORTS-1 downto 0);
+
+ signal writeFrameFull : Array1(PORTS-1 downto 0);
+ signal writeFrame : Array1(PORTS-1 downto 0);
+ signal writeFrameAbort : Array1(PORTS-1 downto 0);
+ signal writeContent : Array1(PORTS-1 downto 0);
+ signal writeContentData : Array32(PORTS-1 downto 0);
+
+ signal readFrameEmpty : Array1(PORTS-1 downto 0);
+ signal readFrame : Array1(PORTS-1 downto 0);
+ signal readContent : Array1(PORTS-1 downto 0);
+ signal readContentEnd : Array1(PORTS-1 downto 0);
+ signal readContentData : Array32(PORTS-1 downto 0);
+
+ signal portLinkTimeout : std_logic_vector(23 downto 0);
+
+ signal linkInitialized : Array1(PORTS-1 downto 0);
+ signal outputPortEnable : Array1(PORTS-1 downto 0);
+ signal inputPortEnable : Array1(PORTS-1 downto 0);
+
+ signal localAckIdWrite : Array1(PORTS-1 downto 0);
+ signal clrOutstandingAckId : Array1(PORTS-1 downto 0);
+ signal inboundAckIdWrite : Array5(PORTS-1 downto 0);
+ signal outstandingAckIdWrite : Array5(PORTS-1 downto 0);
+ signal outboundAckIdWrite : Array5(PORTS-1 downto 0);
+ signal inboundAckIdRead : Array5(PORTS-1 downto 0);
+ signal outstandingAckIdRead : Array5(PORTS-1 downto 0);
+ signal outboundAckIdRead : Array5(PORTS-1 downto 0);
+
+ signal configStb, configStbExpected : std_logic;
+ signal configWe, configWeExpected : std_logic;
+ signal configAddr, configAddrExpected : std_logic_vector(23 downto 0);
+ signal configDataWrite, configDataWriteExpected : std_logic_vector(31 downto 0);
+ signal configDataRead, configDataReadExpected : std_logic_vector(31 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial port emulator.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ ---------------------------------------------------------------------------
+ -- Place a new ingress frame on a port.
+ ---------------------------------------------------------------------------
+ procedure SendFrame(constant portIndex : natural range 0 to 7;
+ constant frame : RioFrame) is
+ begin
+ frameValid(portIndex) <= '1';
+ frameWrite(portIndex) <= frame;
+ wait until frameComplete(portIndex) = '1';
+ frameValid(portIndex) <= '0';
+ end procedure;
+
+ procedure SendFrame(constant portIndex : natural range 0 to 7;
+ constant sourceId : std_logic_vector(15 downto 0);
+ constant destinationId : std_logic_vector(15 downto 0);
+ constant payload : RioPayload) is
+ variable frame : RioFrame;
+ begin
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>sourceId, destId=>destinationId,
+ payload=>payload);
+
+ frameValid(portIndex) <= '1';
+ frameWrite(portIndex) <= frame;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Expect a new egress frame on a port.
+ ---------------------------------------------------------------------------
+ procedure ReceiveFrame(constant portIndex : natural range 0 to 7;
+ constant frame : RioFrame) is
+ begin
+ frameExpected(portIndex) <= '1';
+ frameRead(portIndex) <= frame;
+ wait until frameReceived(portIndex) = '1';
+ frameExpected(portIndex) <= '0';
+ end procedure;
+
+ procedure ReceiveFrame(constant portIndex : natural range 0 to 7;
+ constant sourceId : std_logic_vector(15 downto 0);
+ constant destinationId : std_logic_vector(15 downto 0);
+ constant payload : RioPayload) is
+ variable frame : RioFrame;
+ begin
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>sourceId, destId=>destinationId,
+ payload=>payload);
+
+ frameExpected(portIndex) <= '1';
+ frameRead(portIndex) <= frame;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Read a configuration-space register.
+ ---------------------------------------------------------------------------
+ procedure ReadConfig32(constant portIndex : natural range 0 to 7;
+ constant destinationId : std_logic_vector(15 downto 0);
+ constant sourceId : std_logic_vector(15 downto 0);
+ constant hop : std_logic_vector(7 downto 0);
+ constant tid : std_logic_vector(7 downto 0);
+ constant address : std_logic_vector(23 downto 0);
+ constant data : std_logic_vector(31 downto 0)) is
+ variable maintData : DoubleWordArray(0 to 7);
+ begin
+ SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
+ sourceId=>sourceId, destId=>destinationId,
+ payload=>RioMaintenance(transaction=>"0000",
+ size=>"1000",
+ tid=>tid,
+ hopCount=>hop,
+ configOffset=>address(23 downto 3),
+ wdptr=>address(2),
+ dataLength=>0,
+ data=>maintData)));
+ if (address(2) = '0') then
+ maintData(0) := data & x"00000000";
+ else
+ maintData(0) := x"00000000" & data ;
+ end if;
+
+ ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
+ sourceId=>destinationId, destId=>sourceId,
+ payload=>RioMaintenance(transaction=>"0010",
+ size=>"0000",
+ tid=>tid,
+ hopCount=>x"ff",
+ configOffset=>"000000000000000000000",
+ wdptr=>'0',
+ dataLength=>1,
+ data=>maintData)));
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Write a configuration-space register.
+ ---------------------------------------------------------------------------
+ procedure WriteConfig32(constant portIndex : natural range 0 to 7;
+ constant destinationId : std_logic_vector(15 downto 0);
+ constant sourceId : std_logic_vector(15 downto 0);
+ constant hop : std_logic_vector(7 downto 0);
+ constant tid : std_logic_vector(7 downto 0);
+ constant address : std_logic_vector(23 downto 0);
+ constant data : std_logic_vector(31 downto 0)) is
+ variable maintData : DoubleWordArray(0 to 7);
+ begin
+ if (address(2) = '0') then
+ maintData(0) := data & x"00000000";
+ else
+ maintData(0) := x"00000000" & data ;
+ end if;
+
+ SendFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
+ sourceId=>sourceId, destId=>destinationId,
+ payload=>RioMaintenance(transaction=>"0001",
+ size=>"1000",
+ tid=>tid,
+ hopCount=>hop,
+ configOffset=>address(23 downto 3),
+ wdptr=>address(2),
+ dataLength=>1,
+ data=>maintData)));
+
+ ReceiveFrame(portIndex, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
+ sourceId=>destinationId, destId=>sourceId,
+ payload=>RioMaintenance(transaction=>"0011",
+ size=>"0000",
+ tid=>tid,
+ hopCount=>x"ff",
+ configOffset=>"000000000000000000000",
+ wdptr=>'0',
+ dataLength=>0,
+ data=>maintData)));
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Set a route table entry.
+ ---------------------------------------------------------------------------
+ procedure RouteSet(constant deviceId : std_logic_vector(15 downto 0);
+ constant portIndex : std_logic_vector(7 downto 0)) is
+ variable frame : RioFrame;
+ begin
+ WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00",
+ tid=>x"de", address=>x"000070", data=>(x"0000" & deviceId));
+ WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00",
+ tid=>x"ad", address=>x"000074", data=>(x"000000" & portIndex));
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Set the default route table entry.
+ ---------------------------------------------------------------------------
+ procedure RouteSetDefault(constant portIndex : std_logic_vector(7 downto 0)) is
+ variable frame : RioFrame;
+ begin
+ WriteConfig32(portIndex=>0, destinationId=>x"ffff", sourceId=>x"ffff", hop=>x"00",
+ tid=>x"ad", address=>x"000078", data=>(x"000000" & portIndex));
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Send a frame on an ingress port and expect it at an egress port.
+ ---------------------------------------------------------------------------
+ procedure RouteFrame(constant sourcePortIndex : natural range 0 to 7;
+ constant destinationPortIndex : natural range 0 to 7;
+ constant sourceId : std_logic_vector(15 downto 0);
+ constant destinationId : std_logic_vector(15 downto 0);
+ constant payload : RioPayload) is
+ variable frame : RioFrame;
+ begin
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>sourceId, destId=>destinationId,
+ payload=>payload);
+
+ frameExpected(destinationPortIndex) <= '1';
+ frameRead(destinationPortIndex) <= frame;
+
+ frameValid(sourcePortIndex) <= '1';
+ frameWrite(sourcePortIndex) <= frame;
+ wait until frameComplete(sourcePortIndex) = '1';
+ frameValid(sourcePortIndex) <= '0';
+
+ wait until frameReceived(destinationPortIndex) = '1';
+ frameExpected(destinationPortIndex) <= '0';
+
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Variable definitions.
+ ---------------------------------------------------------------------------
+
+ -- These variabels are needed for the random number generation.
+ variable seed1 : positive := 1;
+ variable seed2: positive := 1;
+
+ variable data : DoubleWordArray(0 to 31);
+ variable randomPayload : RioPayload;
+ variable randomPayload1 : RioPayload;
+ variable randomPayload2 : RioPayload;
+ variable frame : RioFrameArray(0 to PORTS-1);
+
+ begin
+ areset_n <= '0';
+
+ linkInitialized <= (others=>'0');
+
+ for portIndex in 0 to PORTS-1 loop
+ frameValid(portIndex) <= '0';
+ frameExpected(portIndex) <= '0';
+ localAckIdWrite(portIndex) <= '0';
+ clrOutstandingAckId(portIndex) <= '0';
+ inboundAckIdWrite(portIndex) <= (others=>'0');
+ outstandingAckIdWrite(portIndex) <= (others=>'0');
+ outboundAckIdWrite(portIndex) <= (others=>'0');
+ end loop;
+
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSwitch");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSwitch-TC1");
+ PrintS("Description: Test switch maintenance accesses on different ports.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send maintenance read request packets to read switch identity.");
+ PrintS("Result: The switch should answer with its configured identitiy.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step1");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000000", data=>(SWITCH_IDENTITY & SWITCH_VENDOR_IDENTITY));
+ ReadConfig32(portIndex=>1, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"01", address=>x"000004", data=>SWITCH_REV);
+ ReadConfig32(portIndex=>2, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"02", address=>x"000008", data=>(SWITCH_ASSY_IDENTITY & SWITCH_ASSY_VENDOR_IDENTITY));
+ ReadConfig32(portIndex=>3, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"03", address=>x"00000c", data=>(SWITCH_ASSY_REV & x"0100"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Check the switch Processing Element Features.");
+ PrintS("Result: The expected switch features should be returned. ");
+ PrintS(" Switch with extended features pointer valid. Common ");
+ PrintS(" transport large system support and standard route table ");
+ PrintS(" configuration support.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step2");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>4, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"04", address=>x"000010", data=>x"10000118");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Check the switch port information.");
+ PrintS("Result: The expected port and number of ports should be returned.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step3");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>5, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"05", address=>x"000014", data=>x"00000705");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Check the switch number of supported routes.");
+ PrintS("Result: The expected number of supported routes should be returned.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step4");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000034", data=>x"00000800");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Test host base device id lock by reading it, then hold it ");
+ PrintS(" and try to grab it from another address.");
+ PrintS("Result: The value should follow the specification.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Check that the lock is released.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"0000ffff");
+
+ -- Try to accuire the lock.
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000002");
+
+ -- Check that the lock has been accuired.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000002");
+
+ -- Try to accuire the lock from another source.
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000003");
+
+ -- Check that the lock refuses the new access.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000002");
+
+ -- Release the lock.
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000002");
+
+ -- Check that the lock is released.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"0000ffff");
+
+ -- Check that the lock can be accuired from another source once unlocked.
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000003");
+
+ -- Check that the lock is released.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000003");
+
+ -- Release the lock again.
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"00000003");
+
+ -- Check that the lock is released.
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"00", address=>x"000068", data=>x"0000ffff");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6");
+ PrintS("Action: Check the component tag register.");
+ PrintS("Result: The written value in the component tag should be saved.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step6");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00006c", data=>x"00000000");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00006c", data=>x"ffffffff");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00006c", data=>x"ffffffff");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 7");
+ PrintS("Action: Read and write to the port link timeout.");
+ PrintS("Result: Check that the portLinkTimeout output from the switch changes.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step7");
+ ---------------------------------------------------------------------------
+
+ assert portLinkTimeout = x"ffffff" report "Unexpected portLinkTimeout." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000120", data=>x"ffffff00");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000120", data=>x"00000100");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000120", data=>x"00000100");
+
+ assert portLinkTimeout = x"000001" report "Unexpected portLinkTimeout." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 8");
+ PrintS("Action: Read from the port general control.");
+ PrintS("Result: Check the discovered bit.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step8");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00013c", data=>x"00000000");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00013c", data=>x"20000000");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00013c", data=>x"20000000");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00013c", data=>x"00000000");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00013c", data=>x"00000000");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 9");
+ PrintS("Action: Read from the port N error and status.");
+ PrintS("Result: Check the port ok and port uninitialized bits.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step9");
+ ---------------------------------------------------------------------------
+
+ linkInitialized(0) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000158", data=>x"00000001");
+ linkInitialized(0) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000158", data=>x"00000002");
+
+ linkInitialized(1) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000178", data=>x"00000001");
+ linkInitialized(1) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000178", data=>x"00000002");
+
+ linkInitialized(2) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000198", data=>x"00000001");
+ linkInitialized(2) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000198", data=>x"00000002");
+
+ linkInitialized(3) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001b8", data=>x"00000001");
+ linkInitialized(3) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001b8", data=>x"00000002");
+
+ linkInitialized(4) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001d8", data=>x"00000001");
+ linkInitialized(4) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001d8", data=>x"00000002");
+
+ linkInitialized(5) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001f8", data=>x"00000001");
+ linkInitialized(5) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001f8", data=>x"00000002");
+
+ linkInitialized(6) <= '0';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000218", data=>x"00000001");
+ linkInitialized(6) <= '1';
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"000218", data=>x"00000002");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 10");
+ PrintS("Action: Read and write to/from the port N control.");
+ PrintS("Result: Check the output/input port enable.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step10");
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(0) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(0) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00015c", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00015c", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00015c", data=>x"00600001");
+
+ assert outputPortEnable(0) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(0) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(1) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(1) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00017c", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00017c", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00017c", data=>x"00600001");
+
+ assert outputPortEnable(1) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(1) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(2) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(2) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00019c", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00019c", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00019c", data=>x"00600001");
+
+ assert outputPortEnable(2) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(2) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(3) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(3) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001bc", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001bc", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001bc", data=>x"00600001");
+
+ assert outputPortEnable(3) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(3) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(4) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(4) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001dc", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001dc", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001dc", data=>x"00600001");
+
+ assert outputPortEnable(4) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(4) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(5) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(5) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001fc", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001fc", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"0001fc", data=>x"00600001");
+
+ assert outputPortEnable(5) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(5) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+
+ assert outputPortEnable(6) = '0' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(6) = '0' report "Unexpected inputPortEnable." severity error;
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00021c", data=>x"00000001");
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00021c", data=>x"00600001");
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"00021c", data=>x"00600001");
+
+ assert outputPortEnable(6) = '1' report "Unexpected outputPortEnable." severity error;
+ assert inputPortEnable(6) = '1' report "Unexpected inputPortEnable." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 11");
+ PrintS("Action: Read and write to/from the implementation defined space.");
+ PrintS("Result: Check the accesses on the external configuration port.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC1-Step11");
+ ---------------------------------------------------------------------------
+
+ configStbExpected <= '1';
+ configWeExpected <= '0';
+ configAddrExpected <= x"010000";
+ configDataReadExpected <= x"deadbeef";
+
+ ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"010000", data=>x"deadbeef");
+
+ configStbExpected <= '1';
+ configWeExpected <= '1';
+ configAddrExpected <= x"010004";
+ configDataWriteExpected <= x"c0debabe";
+
+ WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"06", address=>x"010004", data=>x"c0debabe");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSwitch-TC2");
+ PrintS("Description: Test the configuration of the routing table and the ");
+ PrintS(" routing of packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Configure the routing table for address 0->port 1.");
+ PrintS("Result: A packet to address 0 should be forwarded to port 1.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"07", address=>x"000070", data=>x"00000000");
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"08", address=>x"000074", data=>x"00000001");
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"09", address=>x"000074", data=>x"00000001");
+
+ -- Send a frame from a port and check if it is correctly routed.
+ randomPayload.length := 3;
+ CreateRandomPayload(randomPayload.data, seed1, seed2);
+ RouteFrame(sourcePortIndex=>0, destinationPortIndex=>1,
+ sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Test the configuration of the default route->port 6.");
+ PrintS("Result: An unknown address should be routed to port 6.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"0a", address=>x"000078", data=>x"00000000");
+ WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"0b", address=>x"000078", data=>x"00000006");
+ ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00",
+ tid=>x"0c", address=>x"000078", data=>x"00000006");
+
+ -- Send a frame from a port and check if it is correctly routed.
+ randomPayload.length := 4;
+ CreateRandomPayload(randomPayload.data, seed1, seed2);
+ RouteFrame(sourcePortIndex=>1, destinationPortIndex=>6,
+ sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSwitch-TC3");
+ PrintS("Description: Test the routing of normal packets.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send two packets but not at the same time.");
+ PrintS("Result: Both packets should be received at the expected ports.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Setup the routing table for the following steps.
+ RouteSet(x"0000", x"00");
+ RouteSet(x"0001", x"00");
+ RouteSet(x"0002", x"00");
+ RouteSet(x"0003", x"00");
+ RouteSet(x"0004", x"01");
+ RouteSet(x"0005", x"02");
+ RouteSet(x"0006", x"03");
+ RouteSetDefault(x"06");
+
+ -- Frame on port 0 to port 1.
+ randomPayload.length := 3;
+ CreateRandomPayload(randomPayload.data, seed1, seed2);
+ SendFrame(portIndex=>0,
+ sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload);
+ ReceiveFrame(portIndex=>1,
+ sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload);
+
+ -- Frame on port 1 to port 6.
+ randomPayload.length := 4;
+ CreateRandomPayload(randomPayload.data, seed1, seed2);
+ SendFrame(portIndex=>1,
+ sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload);
+ ReceiveFrame(portIndex=>6,
+ sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload);
+
+ wait until frameComplete(1) = '1';
+ frameValid(1) <= '0';
+ wait until frameReceived(6) = '1';
+ frameExpected(6) <= '0';
+
+ wait until frameComplete(0) = '1';
+ frameValid(0) <= '0';
+ wait until frameReceived(1) = '1';
+ frameExpected(1) <= '0';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send two packets to the same port that is full and one to");
+ PrintS(" another that is also full. Then receive the packets one at");
+ PrintS(" a time.");
+ PrintS("Result: The packet to the port that is ready should go though.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSwitch-TC3-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Frame on port 0 to port 1.
+ randomPayload.length := 5;
+ CreateRandomPayload(randomPayload.data, seed1, seed2);
+ SendFrame(portIndex=>0,
+ sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload);
+
+ -- Frame on port 1 to port 2.
+ randomPayload1.length := 6;
+ CreateRandomPayload(randomPayload1.data, seed1, seed2);
+ SendFrame(portIndex=>1,
+ sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload1);
+
+ -- Frame on port 2 to port 2.
+ randomPayload2.length := 7;
+ CreateRandomPayload(randomPayload2.data, seed1, seed2);
+ SendFrame(portIndex=>2,
+ sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload2);
+
+ wait for 10 us;
+
+ ReceiveFrame(portIndex=>1,
+ sourceId=>x"ffff", destinationId=>x"0004", payload=>randomPayload);
+ wait until frameComplete(0) = '1';
+ frameValid(0) <= '0';
+ wait until frameReceived(1) = '1';
+ frameExpected(1) <= '0';
+
+ wait for 10 us;
+
+ ReceiveFrame(portIndex=>2,
+ sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload1);
+ wait until frameComplete(1) = '1';
+ frameValid(1) <= '0';
+ wait until frameReceived(2) = '1';
+ frameExpected(2) <= '0';
+
+ wait for 10 us;
+
+ ReceiveFrame(portIndex=>2,
+ sourceId=>x"0000", destinationId=>x"0005", payload=>randomPayload2);
+ wait until frameComplete(2) = '1';
+ frameValid(2) <= '0';
+ wait until frameReceived(2) = '1';
+ frameExpected(2) <= '0';
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ wait for 10 us;
+
+ assert readFrameEmpty = "1111111"
+ report "Pending frames exist." severity error;
+
+ TestEnd;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Instantiate a process receiving the configuration accesses to the
+ -- implementation defined space.
+ -----------------------------------------------------------------------------
+ process
+ begin
+ loop
+ wait until configStb = '1' and clk'event and clk = '1';
+ assert configStb = configStbExpected report "Unexpected configStb." severity error;
+ assert configWe = configWeExpected report "Unexpected configWe." severity error;
+ assert configAddr = configAddrExpected report "Unexpected configAddr." severity error;
+ if (configWe = '1') then
+ assert configDataWrite = configDataWriteExpected report "Unexpected configDataWrite." severity error;
+ else
+ configDataRead <= configDataReadExpected;
+ end if;
+ end loop;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the test port array.
+ -----------------------------------------------------------------------------
+
+ TestPortGeneration: for portIndex in 0 to PORTS-1 generate
+ TestPortInst: TestPort
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ frameValid_i=>frameValid(portIndex),
+ frameWrite_i=>frameWrite(portIndex),
+ frameComplete_o=>frameComplete(portIndex),
+ frameExpected_i=>frameExpected(portIndex),
+ frameRead_i=>frameRead(portIndex),
+ frameReceived_o=>frameReceived(portIndex),
+ readFrameEmpty_o=>readFrameEmpty(portIndex),
+ readFrame_i=>readFrame(portIndex),
+ readContent_i=>readContent(portIndex),
+ readContentEnd_o=>readContentEnd(portIndex),
+ readContentData_o=>readContentData(portIndex),
+ writeFrameFull_o=>writeFrameFull(portIndex),
+ writeFrame_i=>writeFrame(portIndex),
+ writeFrameAbort_i=>writeFrameAbort(portIndex),
+ writeContent_i=>writeContent(portIndex),
+ writeContentData_i=>writeContentData(portIndex));
+ end generate;
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the switch.
+ -----------------------------------------------------------------------------
+
+ TestSwitch: RioSwitch
+ generic map(
+ SWITCH_PORTS=>7,
+ DEVICE_IDENTITY=>SWITCH_IDENTITY,
+ DEVICE_VENDOR_IDENTITY=>SWITCH_VENDOR_IDENTITY,
+ DEVICE_REV=>SWITCH_REV,
+ ASSY_IDENTITY=>SWITCH_ASSY_IDENTITY,
+ ASSY_VENDOR_IDENTITY=>SWITCH_ASSY_VENDOR_IDENTITY,
+ ASSY_REV=>SWITCH_ASSY_REV)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ writeFrameFull_i=>writeFrameFull,
+ writeFrame_o=>writeFrame,
+ writeFrameAbort_o=>writeFrameAbort,
+ writeContent_o=>writeContent,
+ writeContentData_o=>writeContentData,
+ readFrameEmpty_i=>readFrameEmpty,
+ readFrame_o=>readFrame,
+ readContent_o=>readContent,
+ readContentEnd_i=>readContentEnd,
+ readContentData_i=>readContentData,
+ portLinkTimeout_o=>portLinkTimeout,
+ linkInitialized_i=>linkInitialized,
+ outputPortEnable_o=>outputPortEnable,
+ inputPortEnable_o=>inputPortEnable,
+ localAckIdWrite_o=>localAckIdWrite,
+ clrOutstandingAckId_o=>clrOutstandingAckId,
+ inboundAckId_o=>inboundAckIdWrite,
+ outstandingAckId_o=>outstandingAckIdWrite,
+ outboundAckId_o=>outboundAckIdWrite,
+ inboundAckId_i=>inboundAckIdRead,
+ outstandingAckId_i=>outstandingAckIdRead,
+ outboundAckId_i=>outboundAckIdRead,
+ configStb_o=>configStb, configWe_o=>configWe, configAddr_o=>configAddr,
+ configData_o=>configDataWrite, configData_i=>configDataRead);
+
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- Switch port test stub.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestPort.
+-------------------------------------------------------------------------------
+entity TestPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic;
+ frameWrite_i : in RioFrame;
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestPort.
+-------------------------------------------------------------------------------
+architecture TestPortImpl of TestPort is
+begin
+
+ -----------------------------------------------------------------------------
+ -- Egress frame receiver.
+ -----------------------------------------------------------------------------
+ FrameReader: process
+ type StateType is (STATE_IDLE, STATE_WRITE);
+ variable state : StateType;
+ variable frameIndex : natural range 0 to 69;
+ begin
+ writeFrameFull_o <= '1';
+ frameReceived_o <= '0';
+ wait until areset_n = '1';
+
+ state := STATE_IDLE;
+
+ loop
+ wait until clk'event and clk = '1';
+
+ case state is
+
+ when STATE_IDLE =>
+ frameReceived_o <= '0';
+ if (frameExpected_i = '1') then
+ writeFrameFull_o <= '0';
+ state := STATE_WRITE;
+ frameIndex := 0;
+ else
+ writeFrameFull_o <= '1';
+ end if;
+ assert writeFrame_i = '0' report "Unexpected frame." severity error;
+ assert writeFrameAbort_i = '0' report "Unexpected frame abort." severity error;
+ assert writeContent_i = '0' report "Unexpected data." severity error;
+
+ when STATE_WRITE =>
+ if (writeContent_i = '1') then
+ -- Writing content.
+ if (frameIndex < frameRead_i.length) then
+ assert writeContentData_i = frameRead_i.payload(frameIndex)
+ report "Unexpected frame content received:" &
+ " index=" & integer'image(frameIndex) &
+ " expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) &
+ " got=" & integer'image(to_integer(unsigned(writeContentData_i)))
+ severity error;
+
+ frameIndex := frameIndex + 1;
+ else
+ report "Unexpected frame content received:" &
+ " index=" & integer'image(frameIndex) &
+ " expected=" & integer'image(to_integer(unsigned(frameRead_i.payload(frameIndex)))) &
+ " got=" & integer'image(to_integer(unsigned(writeContentData_i)))
+ severity error;
+
+ frameIndex := frameIndex + 1;
+ end if;
+ else
+ -- Not writing any content.
+ end if;
+
+ if (writeFrame_i = '1') then
+ -- Writing a complete frame.
+ assert frameIndex = frameRead_i.length report "Unexpected frame length received." severity error;
+ state := STATE_IDLE;
+ frameReceived_o <= '1';
+ writeFrameFull_o <= '1';
+ else
+ -- Not writing any frame.
+ end if;
+
+ if (writeFrameAbort_i = '1') then
+ -- The frame should be aborted.
+ frameIndex := 0;
+ else
+ -- Not aborting any frame.
+ end if;
+ end case;
+ end loop;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Ingress frame sender.
+ -----------------------------------------------------------------------------
+ FrameSender: process
+ type StateType is (STATE_IDLE, STATE_READ);
+ variable state : StateType;
+ variable frameIndex : natural range 0 to 69;
+ begin
+ readFrameEmpty_o <= '1';
+ readContentEnd_o <= '1';
+ readContentData_o <= (others => 'U');
+ frameComplete_o <= '0';
+ wait until areset_n = '1';
+
+ state := STATE_IDLE;
+
+ loop
+ wait until clk'event and clk = '1';
+
+ case state is
+
+ when STATE_IDLE =>
+ frameComplete_o <= '0';
+ if (frameValid_i = '1') then
+ state := STATE_READ;
+ frameIndex := 0;
+ readFrameEmpty_o <= '0';
+ end if;
+
+ when STATE_READ =>
+ if (readContent_i = '1') then
+ if (frameIndex < frameWrite_i.length) then
+ readContentData_o <= frameWrite_i.payload(frameIndex);
+ readContentEnd_o <= '0';
+ frameIndex := frameIndex + 1;
+ elsif (frameIndex = frameWrite_i.length) then
+ readContentEnd_o <= '1';
+ else
+ report "Reading empty frame." severity error;
+ end if;
+ else
+ -- Not reading data.
+ end if;
+
+ if (readFrame_i = '1') then
+ state := STATE_IDLE;
+ assert frameIndex = frameWrite_i.length report "Unread frame data discarded." severity error;
+ frameComplete_o <= '1';
+ readFrameEmpty_o <= '1';
+ readContentData_o <= (others => 'U');
+ else
+ -- Not reading a frame.
+ end if;
+
+ end case;
+ end loop;
+ end process;
+
+end architecture;
tags/1.0.2-release/bench/vhdl/TestRioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/bench/vhdl/TestRioPcsUart.vhd
===================================================================
--- tags/1.0.2-release/bench/vhdl/TestRioPcsUart.vhd (nonexistent)
+++ tags/1.0.2-release/bench/vhdl/TestRioPcsUart.vhd (revision 50)
@@ -0,0 +1,673 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- This file contains a testbench for RioPcsUart.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- TestRioPcsUart.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioPcsUart.
+-------------------------------------------------------------------------------
+entity TestRioPcsUart is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestRioPcsUartImpl of TestRioPcsUart is
+
+ component RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+ end component;
+
+ component RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal portInitialized : std_logic;
+
+ signal outboundSymbolEmpty : std_logic;
+ signal outboundSymbolRead : std_logic;
+ signal outboundSymbolReadData : std_logic_vector(33 downto 0);
+ signal outboundSymbolFull : std_logic;
+ signal outboundSymbolWrite : std_logic;
+ signal outboundSymbolWriteData : std_logic_vector(33 downto 0);
+
+ signal inboundSymbolFull : std_logic;
+ signal inboundSymbolWrite : std_logic;
+ signal inboundSymbolWriteData : std_logic_vector(33 downto 0);
+
+ signal uartInboundEmpty : std_logic;
+ signal uartInboundRead : std_logic;
+ signal uartInboundReadData : std_logic_vector(7 downto 0);
+ signal uartInboundFull : std_logic;
+ signal uartInboundWrite : std_logic;
+ signal uartInboundWriteData : std_logic_vector(7 downto 0);
+
+ signal uartOutboundFull : std_logic;
+ signal uartOutboundWrite : std_logic;
+ signal uartOutboundWriteData : std_logic_vector(7 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial protocol test driver.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ ---------------------------------------------------------------------------
+ -- Procedure to read a symbol.
+ ---------------------------------------------------------------------------
+ procedure ReadSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ inboundSymbolFull <= '0';
+ wait until inboundSymbolWrite = '1' and clk'event and clk = '1';
+ inboundSymbolFull <= '1';
+
+ assert symbolType = inboundSymbolWriteData(33 downto 32)
+ report "Missmatching symbol type:expected=" &
+ integer'image(to_integer(unsigned(symbolType))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbolWriteData(33 downto 32))))
+ severity error;
+
+ if (symbolType = SYMBOL_CONTROL) then
+ assert symbolContent(31 downto 8) = inboundSymbolWriteData(31 downto 8)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 8)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(inboundSymbolWriteData(31 downto 8))))
+ severity error;
+ elsif (symbolType = SYMBOL_DATA) then
+ assert symbolContent(31 downto 0) = inboundSymbolWriteData(31 downto 0)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 0)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(inboundSymbolWriteData(31 downto 0))))
+ severity error;
+ end if;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to write a symbol.
+ ---------------------------------------------------------------------------
+ procedure WriteSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until outboundSymbolFull = '0' and clk'event and clk = '1';
+ outboundSymbolWrite <= '1';
+ outboundSymbolWriteData <= symbolType & symbolContent;
+ wait until clk'event and clk = '1';
+ outboundSymbolWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to read an octet.
+ ---------------------------------------------------------------------------
+ procedure ReadOctet(
+ constant octet : in std_logic_vector(7 downto 0) := x"00") is
+ begin
+ uartOutboundFull <= '0';
+ wait until uartOutboundWrite = '1' and clk'event and clk = '1';
+ uartOutboundFull <= '1';
+
+ assert uartOutboundWriteData = octet
+ report "Missmatching octet content:expected=" &
+ integer'image(to_integer(unsigned(octet))) &
+ " got=" &
+ integer'image(to_integer(unsigned(uartOutboundWriteData)))
+ severity error;
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to send a symbol.
+ ---------------------------------------------------------------------------
+ procedure WriteOctet(
+ constant octet : in std_logic_vector(7 downto 0) := x"00") is
+ begin
+ wait until uartInboundFull = '0' and clk'event and clk = '1';
+ uartInboundWrite <= '1';
+ uartInboundWriteData <= octet;
+ wait until clk'event and clk = '1';
+ uartInboundWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Process variables.
+ ---------------------------------------------------------------------------
+
+ begin
+ ---------------------------------------------------------------------------
+ -- Test case initialization.
+ ---------------------------------------------------------------------------
+
+ uartOutboundFull <= '1';
+ uartInboundWrite <= '0';
+
+ inboundSymbolFull <= '1';
+ outboundSymbolWrite <= '0';
+
+ -- Generate a startup reset pulse.
+ areset_n <= '0';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC1");
+ PrintS("Description: Check initial silence time.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC1-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+
+ uartOutboundFull <= '0';
+ for i in 0 to 4095 loop
+ wait until clk'event and clk = '1';
+ assert uartOutboundWrite = '0' report "Sending during silence time."
+ severity error;
+ end loop;
+
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC2");
+ PrintS("Description: Check outbound symbol generation.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 2:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 3:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step3");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7d7d7d" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 4:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step4");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7e7e7e" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 5:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step5");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_CONTROL, x"7d7f7e" & "XXXXXXXX");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 6:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step6");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"12345678");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"78");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 7:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step7");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7d7d7d7d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 8:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step8");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7e7e7e7e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 9:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step9");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_DATA, x"7d7f7e7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5d");
+ ReadOctet(x"7f");
+ ReadOctet(x"7d");
+ ReadOctet(x"5e");
+ ReadOctet(x"7f");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step 10:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC2-Step10");
+ ---------------------------------------------------------------------------
+
+ WriteSymbol(SYMBOL_IDLE);
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+ WriteSymbol(SYMBOL_CONTROL, x"123456" & "XXXXXXXX");
+ ReadOctet(x"12");
+ ReadOctet(x"34");
+ ReadOctet(x"56");
+ ReadOctet(x"7e");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+ WriteSymbol(SYMBOL_DATA, x"789abcde");
+ ReadOctet(x"78");
+ ReadOctet(x"9a");
+ ReadOctet(x"bc");
+ ReadOctet(x"de");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPcsUart-TC3");
+ PrintS("Description: Check inbound symbol generation.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7e");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"12");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"34");
+ WriteOctet(x"56");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"78");
+ WriteOctet(x"9a");
+ WriteOctet(x"bc");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"789abc" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"7d7d7d" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_CONTROL, x"7e7e7e" & "XXXXXXXX");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"f1");
+ WriteOctet(x"11");
+ WriteOctet(x"22");
+ WriteOctet(x"33");
+ ReadSymbol(SYMBOL_DATA, x"f1112233");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7e");
+ ReadSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ WriteOctet(x"7d");
+ WriteOctet(x"5d");
+ ReadSymbol(SYMBOL_DATA, x"7d7d7d7d");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ WriteOctet(x"7d");
+ WriteOctet(x"5e");
+ ReadSymbol(SYMBOL_DATA, x"7e7e7e7e");
+
+ ---------------------------------------------------------------------------
+ PrintS("Step :");
+ PrintS("Action: .");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPcsUart-TC3-Step");
+ ---------------------------------------------------------------------------
+
+ WriteOctet(x"44");
+ WriteOctet(x"55");
+ WriteOctet(x"66");
+ WriteOctet(x"77");
+ ReadSymbol(SYMBOL_DATA, x"44556677");
+ WriteOctet(x"88");
+ WriteOctet(x"99");
+ WriteOctet(x"aa");
+ WriteOctet(x"bb");
+ ReadSymbol(SYMBOL_DATA, x"8899aabb");
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+
+ OutboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>outboundSymbolEmpty, read_i=>outboundSymbolRead, data_o=>outboundSymbolReadData,
+ full_o=>outboundSymbolFull, write_i=>outboundSymbolWrite, data_i=>outboundSymbolWriteData);
+
+ InboundOctetFifo: RioFifo1
+ generic map(WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>uartInboundEmpty, read_i=>uartInboundRead, data_o=>uartInboundReadData,
+ full_o=>uartInboundFull, write_i=>uartInboundWrite, data_i=>uartInboundWriteData);
+
+ TestSymbolConverter: RioSymbolConverter
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portInitialized_o=>portInitialized,
+ outboundSymbolEmpty_i=>outboundSymbolEmpty,
+ outboundSymbolRead_o=>outboundSymbolRead, outboundSymbol_i=>outboundSymbolReadData,
+ inboundSymbolFull_i=>inboundSymbolFull,
+ inboundSymbolWrite_o=>inboundSymbolWrite, inboundSymbol_o=>inboundSymbolWriteData,
+ uartEmpty_i=>uartInboundEmpty, uartRead_o=>uartInboundRead, uartData_i=>uartInboundReadData,
+ uartFull_i=>uartOutboundFull, uartWrite_o=>uartOutboundWrite, uartData_o=>uartOutboundWriteData);
+
+end architecture;
tags/1.0.2-release/bench/vhdl/TestRioPcsUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/bench/vhdl/TestUart.vhd
===================================================================
--- tags/1.0.2-release/bench/vhdl/TestUart.vhd (nonexistent)
+++ tags/1.0.2-release/bench/vhdl/TestUart.vhd (revision 50)
@@ -0,0 +1,228 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains a testbench for the generic UART entity.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- TestUart.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestUart.
+-------------------------------------------------------------------------------
+entity TestUart is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestUartImpl of TestUart is
+
+ component Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal rxSerial : std_logic;
+ signal txSerial : std_logic;
+
+ signal rxEmpty : std_logic;
+ signal rxRead : std_logic;
+ signal rxData : std_logic_vector(7 downto 0);
+
+ signal txFull : std_logic;
+ signal txWrite : std_logic;
+ signal txData : std_logic_vector(7 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial port emulator.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ procedure SerialSend(
+ constant data : in std_logic_vector(7 downto 0)) is
+ variable outgoing : std_logic_vector(9 downto 0);
+ begin
+ -- Create the complete transmission character.
+ outgoing(0) := '0';
+ for i in 0 to 7 loop
+ outgoing(i+1) := data(i);
+ end loop;
+ outgoing(9) := '1';
+
+ -- Send the character.
+ for i in 0 to 9 loop
+ txSerial <= outgoing(i);
+ wait for 500 ns;
+ end loop;
+ end procedure;
+
+ procedure SerialReceive(
+ constant data : in std_logic_vector(7 downto 0)) is
+ variable incomming : std_logic_vector(9 downto 0);
+ begin
+ -- Receive the character.
+ wait until rxSerial = '0';
+ incomming(0) := '0';
+ for i in 1 to 9 loop
+ wait for 500 ns;
+ incomming(i) := rxSerial;
+ end loop;
+
+ -- Check if the received character is expected.
+ assert (incomming(0) = '0') report "Start bit." severity error;
+ assert (incomming(8 downto 1) = data) report "Data bit" severity error;
+ assert (incomming(9) = '1') report "Stop bit." severity error;
+ end procedure;
+
+ begin
+ txSerial <= '1';
+ txWrite <= '0';
+ rxRead <= '0';
+ areset_n <= '0';
+
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ -- Send byte to uart.
+ ---------------------------------------------------------------------------
+ SerialSend(x"55");
+ wait until rxEmpty = '0' and clk'event and clk = '1';
+ rxRead <= '1';
+ wait until clk'event and clk = '1';
+ rxRead <= '0';
+ wait until clk'event and clk = '1';
+ assert rxData = x"55" report "rxData" severity error;
+
+ SerialSend(x"62");
+ wait until rxEmpty = '0' and clk'event and clk = '1';
+ rxRead <= '1';
+ wait until clk'event and clk = '1';
+ rxRead <= '0';
+ wait until clk'event and clk = '1';
+ assert rxData = x"62" report "rxData" severity error;
+
+ wait until txFull = '0' and clk'event and clk = '1';
+ txWrite <= '1';
+ txData <= x"55";
+ wait until clk'event and clk = '1';
+ txWrite <= '0';
+ SerialReceive(x"55");
+
+ wait until txFull = '0' and clk'event and clk = '1';
+ txWrite <= '1';
+ txData <= x"62";
+ wait until clk'event and clk = '1';
+ txWrite <= '0';
+ SerialReceive(x"62");
+
+ -- REMARK: Formalize the tests and write more testcases...
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the uart.
+ -----------------------------------------------------------------------------
+
+ UartInst: Uart
+ generic map(DIVISOR_WIDTH=>4, DATA_WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ divisor_i=>"1011",
+ serial_i=>txSerial, serial_o=>rxSerial,
+ empty_o=>rxEmpty, read_i=>rxRead, data_o=>rxData,
+ full_o=>txFull, write_i=>txWrite, data_i=>txData);
+
+end architecture;
tags/1.0.2-release/bench/vhdl/TestUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/bench/vhdl/TestRioSerial.vhd
===================================================================
--- tags/1.0.2-release/bench/vhdl/TestRioSerial.vhd (nonexistent)
+++ tags/1.0.2-release/bench/vhdl/TestRioSerial.vhd (revision 50)
@@ -0,0 +1,2486 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains automatic simulation test code to verify a RioSerial implementation.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- TestRioSerial.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioSerial.
+-------------------------------------------------------------------------------
+entity TestRioSerial is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestUart.
+-------------------------------------------------------------------------------
+architecture TestRioSerialImpl of TestRioSerial is
+
+ component TestSwitchPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic_vector(0 to 63);
+ frameWrite_i : in RioFrameArray(0 to 63);
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component RioSerial is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ linkInitialized_o : out std_logic;
+ inputPortEnable_i : in std_logic;
+ outputPortEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ portInitialized_i : in std_logic;
+ outboundSymbolEmpty_o : out std_logic;
+ outboundSymbolRead_i : in std_logic;
+ outboundSymbol_o : out std_logic_vector(33 downto 0);
+ inboundSymbolFull_o : out std_logic;
+ inboundSymbolWrite_i : in std_logic;
+ inboundSymbol_i : in std_logic_vector(33 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal uartInbound : std_logic;
+ signal uartOutbound : std_logic;
+
+ signal portLinkTimeout : std_logic_vector(10 downto 0);
+ signal linkInitialized : std_logic;
+ signal inputPortEnable : std_logic;
+ signal outputPortEnable : std_logic;
+
+ signal localAckIdWrite : std_logic;
+ signal clrOutstandingAckId : std_logic;
+ signal inboundAckIdWrite : std_logic_vector(4 downto 0);
+ signal outstandingAckIdWrite : std_logic_vector(4 downto 0);
+ signal outboundAckIdWrite : std_logic_vector(4 downto 0);
+ signal inboundAckIdRead : std_logic_vector(4 downto 0);
+ signal outstandingAckIdRead : std_logic_vector(4 downto 0);
+ signal outboundAckIdRead : std_logic_vector(4 downto 0);
+
+ signal portInitialized : std_logic;
+ signal outboundSymbolEmpty : std_logic;
+ signal outboundSymbolRead : std_logic;
+ signal outboundSymbol : std_logic_vector(33 downto 0);
+ signal inboundSymbolFull : std_logic;
+ signal inboundSymbolWrite : std_logic;
+ signal inboundSymbol : std_logic_vector(33 downto 0);
+
+ signal readFrameEmpty : std_logic;
+ signal readFrame : std_logic;
+ signal readFrameRestart : std_logic;
+ signal readFrameAborted : std_logic;
+ signal readWindowEmpty : std_logic;
+ signal readWindowReset : std_logic;
+ signal readWindowNext : std_logic;
+ signal readContentEmpty : std_logic;
+ signal readContent : std_logic;
+ signal readContentEnd : std_logic;
+ signal readContentData : std_logic_vector(31 downto 0);
+
+ signal writeFrameFull : std_logic;
+ signal writeFrame : std_logic;
+ signal writeFrameAbort : std_logic;
+ signal writeContent : std_logic;
+ signal writeContentData : std_logic_vector(31 downto 0);
+
+ signal frameValid : std_logic_vector(0 to 63);
+ signal frameWrite : RioFrameArray(0 to 63);
+ signal frameComplete : std_logic;
+ signal frameExpected : std_logic;
+ signal frameRead : RioFrame;
+ signal frameReceived : std_logic;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Serial protocol test driver.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+
+ ---------------------------------------------------------------------------
+ -- Procedure to receive a symbol.
+ ---------------------------------------------------------------------------
+ procedure ReceiveSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until outboundSymbolEmpty = '0' and clk'event and clk = '1';
+
+ assert symbolType = outboundSymbol(33 downto 32)
+ report "Missmatching symbol type:expected=" &
+ integer'image(to_integer(unsigned(symbolType))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(33 downto 32))))
+ severity error;
+
+ if ((outboundSymbol(33 downto 32) = SYMBOL_CONTROL) or
+ (outboundSymbol(33 downto 32) = SYMBOL_CONTROL)) then
+ assert symbolContent(31 downto 8) = outboundSymbol(31 downto 8)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 8)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(31 downto 8))))
+ severity error;
+ elsif (outboundSymbol(33 downto 32) = SYMBOL_DATA) then
+ assert symbolContent(31 downto 0) = outboundSymbol(31 downto 0)
+ report "Missmatching symbol content:expected=" &
+ integer'image(to_integer(unsigned(symbolContent(31 downto 0)))) &
+ " got=" &
+ integer'image(to_integer(unsigned(outboundSymbol(31 downto 0))))
+ severity error;
+ end if;
+
+ outboundSymbolRead <= '1';
+ wait until clk'event and clk = '1';
+ outboundSymbolRead <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to send a symbol.
+ ---------------------------------------------------------------------------
+ procedure SendSymbol(
+ constant symbolType : in std_logic_vector(1 downto 0);
+ constant symbolContent : in std_logic_vector(31 downto 0) := x"00000000") is
+ begin
+ wait until inboundSymbolFull = '0' and clk'event and clk = '1';
+
+ inboundSymbolWrite <= '1';
+ inboundSymbol <= symbolType & symbolContent;
+
+ wait until clk'event and clk = '1';
+ inboundSymbolWrite <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Process variables.
+ ---------------------------------------------------------------------------
+ variable seed1 : positive := 1;
+ variable seed2 : positive := 1;
+ variable payload : RioPayload;
+
+ variable frame : RioFrame;
+
+ begin
+ ---------------------------------------------------------------------------
+ -- Test case initialization.
+ ---------------------------------------------------------------------------
+
+ frameValid <= (others=>'0');
+ frameExpected <= '0';
+
+ portLinkTimeout <= (others=>'1');
+ inputPortEnable <= '1';
+ outputPortEnable <= '1';
+
+ portInitialized <= '0';
+ outboundSymbolRead <= '0';
+ inboundSymbolWrite <= '0';
+ inboundSymbol <= (others => '0');
+
+ localAckIdWrite <= '0';
+ clrOutstandingAckId <= '0';
+ inboundAckIdWrite <= (others=>'0');
+ outstandingAckIdWrite <= (others=>'0');
+ outboundAckIdWrite <= (others=>'0');
+
+ -- Generate a startup reset pulse.
+ areset_n <= '0';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC1");
+ PrintS("Description: Test idle-sequence transmission at startup.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Read transmission port.");
+ PrintS("Result: Idle sequence symbols should be read.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC1-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Make sure only idle-sequences are transmitted at startup.
+ for i in 0 to 1024 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC2");
+ PrintS("Description: Test idle-sequence and status symbol transmission");
+ PrintS(" when the port has been initialized.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Set port initialized and read transmission port.");
+ PrintS("Result: Idle sequence and status symbols should be read.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Initialize the port to trigger a change of state.
+ portInitialized <= '1';
+
+ -- The transmitter should send idle sequences at startup and a status once
+ -- in a while.
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Toggle port initialized pin and check that no status ");
+ PrintS(" symbols are transmitted when uninitialized.");
+ PrintS("Result: Only idle sequences should be read when uninitialized.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Deassert the port initialized flag.
+ portInitialized <= '0';
+
+ -- Make sure only idle-sequences are transmitted at startup.
+ for i in 0 to 1024 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ -- Initialize the port to trigger a change of state.
+ portInitialized <= '1';
+
+ -- The transmitter should send idle sequences at startup and a status once
+ -- in a while.
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ for i in 0 to 254 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send one error free status symbol to trigger the ");
+ PrintS(" transmission of status symbols with a higher frequency.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should be recived more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step3");
+ ---------------------------------------------------------------------------
+
+ -- A received error-free status triggers transmission of status symbols in
+ -- a more rapid past.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- The transmitter should send at least 15 additional statuses after
+ -- receiving an error free status.
+ for j in 0 to 15 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send one errornous status symbol to restart the status ");
+ PrintS(" counting.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should still be received more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step4");
+ ---------------------------------------------------------------------------
+
+ -- REMARK: Add this...
+ PrintR("Not implemented.");
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Send one errornous status symbol to restart the status ");
+ PrintS(" counting.");
+ PrintS("Result: Idle sequence and status symbols should be read but ");
+ PrintS(" status symbols should still be received more often.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC2-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Make the link fully initialized by sending 7 additional statuses.
+ for i in 0 to 6 loop
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ wait until linkInitialized = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC3");
+ PrintS("Description: Test port reception.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send an inbound frame with pad after the CRC.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 1;
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send an inbound frame without a pad after the CRC.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 2;
+ frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmited frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send an inbound frame with maximum size.");
+ PrintS("Result: The frame should end up in a frame buffer.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step3");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 133;
+ frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send two packets without end-of-packet in between.");
+ PrintS("Result: Both packets should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step4");
+ ---------------------------------------------------------------------------
+
+ -- Create the first frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Start the reception of a frame, implicitly ending the previous.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+ wait until clk'event and clk = '1';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the second frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- End the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Start to send a packet. Abort it with stomp. Then send ");
+ PrintS(" another packet.");
+ PrintS("Result: The first packet should be discarded and the second should");
+ PrintS(" be accepted. The retried packet should be acknowledged.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 7;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_STOMP, "000"));
+
+ -- Dont expect the aborted frame anymore.
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the retry was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00101", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the canceled packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00101", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Start to send a packet but dont send any payload. Abort it");
+ PrintS(" with stomp. Then send another packet.");
+ PrintS("Result: The first packet should be discarded and the second should");
+ PrintS(" be accepted. The retried packet should be acknowledged.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step6");
+ ---------------------------------------------------------------------------
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_STOMP, "000"));
+
+ -- Receive an idle symbol left in the FIFO before the retry was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the canceled packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Start to send a packet with payload, then send a ");
+ PrintS(" link-request. Then send another packet.");
+ PrintS("Result: The first packet should be canceled without any ");
+ PrintS(" confirmation and a link-response should be returned. The");
+ PrintS(" second packet should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step7");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 9;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Send a link-request/input-status to abort the current packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- The frame should be canceled by the link-request, dont expect it anymore.
+ frameExpected <= '0';
+
+ -- Receive link-response indicating normal operation and expected ackId.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00111", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Start to send a packet, no payload, then send a ");
+ PrintS(" link-request. Then send another packet.");
+ PrintS("Result: The first packet should be canceled without any ");
+ PrintS(" confirmation and a link-response should be returned. The");
+ PrintS(" second packet should be accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step8");
+ ---------------------------------------------------------------------------
+
+ -- Expect an empty packet to be aborted.
+ frameExpected <= '1';
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send a link-request/input-status to abort the current packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Dont expect any frames anymore.
+ frameExpected <= '0';
+
+ -- Receive link-response indicating normal operation and expected ackId.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Send the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Abort the reception of the frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Check that the frame has been received in the frame buffer.
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive an idle symbol left in the FIFO before the ack was generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Send a packet when no buffers is available. Reset receiver");
+ PrintS(" with link-request.");
+ PrintS("Result: A packet-retry should be transmitted and receiver should");
+ PrintS(" enter input-retry-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step9");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ -- This should also set the receiver into normal operation.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "00100",
+ STYPE1_NOP, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 10:");
+ PrintS("Action: Send a packet when no buffers is available. Reset receiver");
+ PrintS(" with restart-from-retry.");
+ PrintS("Result: A packet-retry should be transmitted and receiver should");
+ PrintS(" enter input-retry-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step10");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Acknowledge the retried packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Check the status of the input port and verify the input-retry-stopped state.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "10000",
+ STYPE1_NOP, "000"));
+
+ -- Always receive a status after a link response when leaving input-error-stopped.
+-- ReceiveSymbol(SYMBOL_CONTROL,
+-- RioControlSymbolCreate(STYPE0_STATUS, "01001", "11111",
+-- STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 11:");
+ PrintS("Action: Start a new packet when in input-retry-stopped state.");
+ PrintS("Result: The packet should be discarded.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step11");
+ ---------------------------------------------------------------------------
+
+ -- Create a new frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+
+ -- Start the reception of a frame.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_DATA, frame.payload(0));
+
+ -- Receive notification about that the packet needs to be retried.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create a packet and send it. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 12;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Acknowledge the retried packet.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Create a packet and send it.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 12:");
+ PrintS("Action: Send an erronous control-symbol. Then restore with");
+ PrintS(" link-request.");
+ PrintS("Result: Receiver should enter input-error-stopped and return to");
+ PrintS(" normal operation after the link-request was receiver.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step12");
+ ---------------------------------------------------------------------------
+
+ -- Create, corrupt and send a control symbol.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000") xor x"00100000");
+
+ -- Receive a packet-not-accepted indicating error in control-symbol crc.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00010",
+ STYPE1_NOP, "000"));
+
+ -- Create a packet and send it. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 14;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Make the receiver go back to normal operation by sending a link-request.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01010", "00101",
+ STYPE1_NOP, "000"));
+
+ -- Always receive a status after a link response when leaving input-error-stopped.
+-- ReceiveSymbol(SYMBOL_CONTROL,
+-- RioControlSymbolCreate(STYPE0_STATUS, "01010", "11111",
+-- STYPE1_NOP, "000"));
+
+ -- Create a packet and send it.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 15;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01010", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 13:");
+ PrintS("Action: Send an erronous packet. Then restore with link-request.");
+ PrintS("Result: Receiver should enter input-error-stopped and return to");
+ PrintS(" normal operation after the link-request was receiver.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC3-Step13");
+ ---------------------------------------------------------------------------
+
+ -- Create a packet and send it with a bit error. It should be discarded.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 15;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frame.payload(0) := frame.payload(0) xor x"00000010";
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Receive a packet-not-accepted indicating error in control-symbol crc.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "00100",
+ STYPE1_NOP, "000"));
+
+ -- Dont expect any frame anymore.
+ frameExpected <= '0';
+
+ -- Make the receiver go back to normal operation by sending a link-request.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "00101",
+ STYPE1_NOP, "000"));
+
+ -- Send a new frame without error.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 16;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameExpected <= '1';
+ frameRead <= frame;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ SendSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00000", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ wait until frameReceived = '1';
+ frameExpected <= '0';
+
+ -- Receive acknowledge for the transmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- REMARK: Complete with some more error situations: invalid ackId, too
+ -- short packet, too long packet, etc...
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioSerial-TC4");
+ PrintS("Description: Test port transmission.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Send an outbound frame.");
+ PrintS("Result: The frame should be read from the frame buffer and ");
+ PrintS(" received as symbols.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step1");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 3;
+ frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(0) <= '1';
+ frameWrite(0) <= frame;
+
+ -- Make sure the transmitter fills in the correct ackId and dont use the
+ -- one in the input packet.
+ frameWrite(0).payload(0)(31 downto 27) <= "UUUUU";
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(0) <= '0';
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Send an outbound packet with maximum length.");
+ PrintS("Result: The packet should be fragmented and received in symbols.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step2");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 133;
+ frame := RioFrameCreate(ackId=>"00001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(1) <= '1';
+ frameWrite(1) <= frame;
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(1) <= '0';
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Send a packet and confirm it with packet-retry.");
+ PrintS("Result: A restart-from-retry should be transmitted and the packet");
+ PrintS(" should be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step3");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 4;
+ frame := RioFrameCreate(ackId=>"00010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(2) <= '1';
+ frameWrite(2) <= frame;
+
+ -- Receive an idle symbol left in the FIFO before the start of the frame was
+ -- generated.
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send packet-retry that the frame should be retransmitted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the acknowledgement for the retransmission.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_RESTART_FROM_RETRY, "000"));
+
+ -- Receive the start of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the retransmitted frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1' and clk'event and clk = '1';
+ frameValid(2) <= '0';
+
+ -- Receive the end of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00010", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Send a packet and confirm it with packet-not-accepted. ");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step4");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 5;
+ frame := RioFrameCreate(ackId=>"00011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(3) <= '1';
+ frameWrite(3) <= frame;
+
+ -- Receive the start of the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Receive the end of the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send packet-retry that the frame should be retransmitted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_NOT_ACCEPTED, "00000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the acknowledgement for the retransmission.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the start of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ -- Receive the data symbols of the retransmitted frame.
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(3) <= '0';
+
+ -- Receive the end of the retransmitted frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00011", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Let a packet timeout expire. Then answer with link-response.");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step5");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 5;
+ frame := RioFrameCreate(ackId=>"00100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(4) <= '1';
+ frameWrite(4) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response to make the transmitter to back to normal mode.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive the retransmitted frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ -- Wait for the frame to complete.
+ wait until frameComplete = '1';
+ frameValid(4) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send acknowledge that the frame was received.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00100", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Let a packet timeout expire. Then answer with link-response");
+ Prints(" that indicates that the packet was received.");
+ PrintS("Result: A link-request should be transmitted and the packet should");
+ PrintS(" not be retransmitted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step6");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 6;
+ frame := RioFrameCreate(ackId=>"00101", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(5) <= '1';
+ frameWrite(5) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(5) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response that indicates that the frame was received to make
+ -- the transmitter to back to normal mode.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 7:");
+ PrintS("Action: Let a packet timeout expire. No more replies.");
+ PrintS("Result: Three link-requests should be transmitted. When the third");
+ PrintS(" times out the link will be restarted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step7");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 7;
+ frame := RioFrameCreate(ackId=>"00110", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(6) <= '1';
+ frameWrite(6) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+
+ -- Reinitialize the transmitter.
+ for i in 0 to 255 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00110", "11111",
+ STYPE1_NOP, "000"));
+ for j in 0 to 14 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(6) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00110", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 8:");
+ PrintS("Action: Let a packet timeout expire. Then answer with totally ");
+ PrintS(" unexpected ackId.");
+ PrintS("Result: A link request should be transmitted and the link should ");
+ PrintS(" be restarted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step8");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 8;
+ frame := RioFrameCreate(ackId=>"00111", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(7) <= '1';
+ frameWrite(7) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Wait a while to let the timer expire and receive the link-request.
+ for i in 0 to 2048 loop
+ wait until clk'event and clk = '1';
+ end loop;
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Reinitialize the transmitter.
+ for i in 0 to 255 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "00111", "11111",
+ STYPE1_NOP, "000"));
+ for j in 0 to 14 loop
+ for i in 0 to 15 loop
+ ReceiveSymbol(SYMBOL_IDLE);
+ end loop;
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_NOP, "000"));
+ end loop;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(7) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "00111", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 9:");
+ PrintS("Action: Send status with unexpected ackId in normal operation.");
+ PrintS("Result: The transmitter should disregard the error.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step9");
+ ---------------------------------------------------------------------------
+
+ -- Send a status with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive no change.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 10:");
+ PrintS("Action: Send packet-retry with unexpected ackId in normal operation.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step10");
+ ---------------------------------------------------------------------------
+
+ -- Send a packet-retry with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_RETRY, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 10;
+ frame := RioFrameCreate(ackId=>"01000", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(8) <= '1';
+ frameWrite(8) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(8) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01000", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 11:");
+ PrintS("Action: Send packet-accepted with unexpected ackId in normal ");
+ PrintS(" operation.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step11");
+ ---------------------------------------------------------------------------
+
+ -- Send a packet-accepted with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with unexpected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 11;
+ frame := RioFrameCreate(ackId=>"01001", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(9) <= '1';
+ frameWrite(9) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(9) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01001", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 12:");
+ PrintS("Action: Send a packet and then accept it with unexpected ackId.");
+ PrintS("Result: The transmitter should enter output-error-stopped.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step12");
+ ---------------------------------------------------------------------------
+
+ -- Create the frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 12;
+ frame := RioFrameCreate(ackId=>"01010", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(10) <= '1';
+ frameWrite(10) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frame.length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frame.payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(10) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+ -- Send unexpected ackId in packet-accepted.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "10000", "11111",
+ STYPE1_NOP, "000"));
+
+ -- Receive link-request.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_LINK_REQUEST, "100"));
+
+ -- Send a link-response with expected ackId.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_LINK_RESPONSE, "01011", "11111",
+ STYPE1_NOP, "000"));
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 13:");
+ PrintS("Action: Set two valid packets.");
+ PrintS("Result: The two packet should be sent without waiting for ");
+ PrintS(" packet-accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step13");
+ ---------------------------------------------------------------------------
+
+ -- Create the first frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 13;
+ frame := RioFrameCreate(ackId=>"01011", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(11) <= '1';
+ frameWrite(11) <= frame;
+
+ -- Create the second frame.
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := 14;
+ frame := RioFrameCreate(ackId=>"01100", vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(12) <= '1';
+ frameWrite(12) <= frame;
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(11).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(11).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(11) <= '0';
+
+ -- Receive the frame.
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(12).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(12).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(12) <= '0';
+
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_END_OF_PACKET, "000"));
+
+
+ -- Send packet-accepted for both packets.
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01011", "11111",
+ STYPE1_NOP, "000"));
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01100", "11111",
+ STYPE1_NOP, "000"));
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 14:");
+ PrintS("Action: Set maximum number of valid packets.");
+ PrintS("Result: Maximum 31 packets should be sent without waiting for ");
+ PrintS(" packet-accepted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-Step14");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Create the frames.
+ ---------------------------------------------------------------------------
+
+ for j in 0 to 47 loop
+ CreateRandomPayload(payload.data, seed1, seed2);
+ payload.length := j+13;
+ frame := RioFrameCreate(ackId=>std_logic_vector(to_unsigned((j+13) mod 32, 5)), vc=>'0', crf=>'0', prio=>"00",
+ tt=>"01", ftype=>"0000",
+ sourceId=>x"0000", destId=>x"0000",
+ payload=>payload);
+ frameValid(j+13) <= '1';
+ frameWrite(j+13) <= frame;
+ end loop;
+
+ ---------------------------------------------------------------------------
+ -- Receive the frames.
+ ---------------------------------------------------------------------------
+
+ ReceiveSymbol(SYMBOL_IDLE);
+
+ for j in 0 to 30 loop
+ ReceiveSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_STATUS, "01100", "11111",
+ STYPE1_START_OF_PACKET, "000"));
+ for i in 0 to frameWrite(j+13).length-1 loop
+ ReceiveSymbol(SYMBOL_DATA, frameWrite(j+13).payload(i));
+ end loop;
+
+ wait until frameComplete = '1';
+ frameValid(j+13) <= '0';
+ end loop;
+
+ ReceiveSymbol(SYMBOL_IDLE);
+ ReceiveSymbol(SYMBOL_IDLE);
+
+
+ SendSymbol(SYMBOL_CONTROL,
+ RioControlSymbolCreate(STYPE0_PACKET_ACCEPTED, "01101", "11111",
+ STYPE1_NOP, "000"));
+
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step X:");
+ PrintS("Action: Start sending an outbound packet and while in transmission, ");
+ PrintS(" start and complete an inbound packet.");
+ PrintS("Result: The ack for the inbound packet should be inserted into the");
+ PrintS(" outbound packet.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-StepX");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step X:");
+ PrintS("Action: Send a packet but not all content is available yet.");
+ PrintS("Result: Idle symbols should be inserted into the packet.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioSerial-TC4-StepX");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- REMARK: Send long frames with a CRC in the middle...
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the uart.
+ -----------------------------------------------------------------------------
+
+ TestPort: TestSwitchPort
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ frameValid_i=>frameValid, frameWrite_i=>frameWrite, frameComplete_o=>frameComplete,
+ frameExpected_i=>frameExpected, frameRead_i=>frameRead, frameReceived_o=>frameReceived,
+ readFrameEmpty_o=>readFrameEmpty, readFrame_i=>readFrame,
+ readFrameRestart_i=>readFrameRestart, readFrameAborted_o=>readFrameAborted,
+ readWindowEmpty_o=>readWindowEmpty,
+ readWindowReset_i=>readWindowReset, readWindowNext_i=>readWindowNext,
+ readContentEmpty_o=>readContentEmpty, readContent_i=>readContent,
+ readContentEnd_o=>readContentEnd, readContentData_o=>readContentData,
+ writeFrameFull_o=>writeFrameFull, writeFrame_i=>writeFrame, writeFrameAbort_i=>writeFrameAbort,
+ writeContent_i=>writeContent, writeContentData_i=>writeContentData);
+
+ TestPhy: RioSerial
+ generic map(
+ TIMEOUT_WIDTH=>11)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portLinkTimeout_i=>portLinkTimeout,
+ linkInitialized_o=>linkInitialized,
+ inputPortEnable_i=>inputPortEnable,
+ outputPortEnable_i=>outputPortEnable,
+ localAckIdWrite_i=>localAckIdWrite,
+ clrOutstandingAckId_i=>clrOutstandingAckId,
+ inboundAckId_i=>inboundAckIdWrite,
+ outstandingAckId_i=>outstandingAckIdWrite,
+ outboundAckId_i=>outboundAckIdWrite,
+ inboundAckId_o=>inboundAckIdRead,
+ outstandingAckId_o=>outstandingAckIdRead,
+ outboundAckId_o=>outboundAckIdRead,
+ readFrameEmpty_i=>readFrameEmpty, readFrame_o=>readFrame, readFrameRestart_o=>readFrameRestart,
+ readFrameAborted_i=>readFrameAborted,
+ readWindowEmpty_i=>readWindowEmpty,
+ readWindowReset_o=>readWindowReset, readWindowNext_o=>readWindowNext,
+ readContentEmpty_i=>readContentEmpty,
+ readContent_o=>readContent, readContentEnd_i=>readContentEnd, readContentData_i=>readContentData,
+ writeFrameFull_i=>writeFrameFull, writeFrame_o=>writeFrame, writeFrameAbort_o=>writeFrameAbort,
+ writeContent_o=>writeContent, writeContentData_o=>writeContentData,
+ portInitialized_i=>portInitialized,
+ outboundSymbolEmpty_o=>outboundSymbolEmpty, outboundSymbolRead_i=>outboundSymbolRead,
+ outboundSymbol_o=>outboundSymbol,
+ inboundSymbolFull_o=>inboundSymbolFull, inboundSymbolWrite_i=>inboundSymbolWrite,
+ inboundSymbol_i=>inboundSymbol);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity TestSwitchPort is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ frameValid_i : in std_logic_vector(0 to 63);
+ frameWrite_i : in RioFrameArray(0 to 63);
+ frameComplete_o : out std_logic;
+
+ frameExpected_i : in std_logic;
+ frameRead_i : in RioFrame;
+ frameReceived_o : out std_logic;
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(31 downto 0);
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture TestSwitchPortImpl of TestSwitchPort is
+begin
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ FrameSender: process
+ variable frameIndex : natural range 0 to 70;
+ variable backIndex, frontIndex : natural range 0 to 63;
+ begin
+ readFrameEmpty_o <= '1';
+ readFrameAborted_o <= '0';
+ readWindowEmpty_o <= '1';
+ readContentEmpty_o <= '1';
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ frameComplete_o <= '0';
+ backIndex := 0;
+ frontIndex := 0;
+ wait until areset_n = '1';
+
+ loop
+ wait until clk'event and clk = '1';
+
+ if (readFrame_i = '1') then
+ assert (frontIndex - backIndex) >= 0 report "Unexpected readFrame." severity error;
+ if(backIndex < 63) then
+ backIndex := backIndex + 1;
+ else
+ backIndex := 0;
+ end if;
+ end if;
+
+ if (readWindowReset_i = '1') then
+ frameIndex := 0;
+ frontIndex := backIndex;
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ end if;
+
+ if (readWindowNext_i = '1') then
+ assert frameIndex = frameWrite_i(frontIndex).length report "Did not read all frame content." severity error;
+ frameComplete_o <= '1';
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ frameIndex := 0;
+ if(frontIndex < 63) then
+ frontIndex := frontIndex + 1;
+ else
+ frontIndex := 0;
+ end if;
+ else
+ frameComplete_o <= '0';
+ end if;
+
+ if (readFrameRestart_i = '1') then
+ frameIndex := 0;
+ readContentEnd_o <= '0';
+ readContentData_o <= (others=>'U');
+ end if;
+
+ if (readContent_i = '1') then
+ assert frameValid_i(frontIndex) = '1' report "Unexpected content read." severity error;
+ if (frameIndex /= frameWrite_i(frontIndex).length) then
+ readContentEnd_o <= '0';
+ readContentData_o <= frameWrite_i(frontIndex).payload(frameIndex);
+ frameIndex := frameIndex + 1;
+ else
+ readContentEnd_o <= '1';
+ readContentData_o <= (others=>'U');
+ end if;
+ end if;
+
+ if(frameValid_i(frontIndex) = '1') then
+ readFrameEmpty_o <= '0';
+ readWindowEmpty_o <= '0';
+ readContentEmpty_o <= '0';
+ else
+ readFrameEmpty_o <= '1';
+ readWindowEmpty_o <= '1';
+ readContentEmpty_o <= '1';
+ end if;
+
+ end loop;
+ end process;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ FrameReader: process
+ type StateType is (STATE_IDLE, STATE_READ, STATE_UPDATE);
+ variable state : StateType;
+ variable frameIndex : natural range 0 to 69;
+ begin
+ writeFrameFull_o <= '1';
+ frameReceived_o <= '0';
+ wait until areset_n = '1';
+
+ state := STATE_IDLE;
+
+ loop
+ wait until clk'event and clk = '1';
+
+ case state is
+ when STATE_IDLE =>
+ frameReceived_o <= '0';
+ if (frameExpected_i = '1') then
+ state := STATE_READ;
+ frameIndex := 0;
+ writeFrameFull_o <= '0';
+ end if;
+ assert writeFrame_i = '0' report "Unexpected frame received." severity error;
+ --assert writeFrameAbort_i = '0' report "Unexpected frame aborted received." severity error;
+ assert writeContent_i = '0' report "Unexpected content received." severity error;
+
+ when STATE_READ =>
+ if (writeFrame_i = '1') then
+ state := STATE_UPDATE;
+ frameReceived_o <= '1';
+ writeFrameFull_o <= '1';
+ assert frameIndex = frameRead_i.length report "Did not finish the expected frame." severity error;
+ end if;
+ if (writeFrameAbort_i = '1') then
+ frameIndex := 0;
+ end if;
+ if (writeContent_i = '1') then
+ assert writeContentData_i = frameRead_i.payload(frameIndex)
+ report "Unexpected frame content received." severity error;
+ frameIndex := frameIndex + 1;
+ end if;
+ if (frameExpected_i = '0') then
+ state := STATE_IDLE;
+ end if;
+
+ when STATE_UPDATE =>
+ if (frameExpected_i = '0') then
+ state := STATE_IDLE;
+ end if;
+
+ end case;
+ end loop;
+ end process;
+
+end architecture;
tags/1.0.2-release/bench/vhdl/TestRioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/bench/vhdl/TestRioPacketBuffer.vhd
===================================================================
--- tags/1.0.2-release/bench/vhdl/TestRioPacketBuffer.vhd (nonexistent)
+++ tags/1.0.2-release/bench/vhdl/TestRioPacketBuffer.vhd (revision 50)
@@ -0,0 +1,2247 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains automatic simulation test code to verify a RioPacketBufferWindow
+-- implementation.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- TestRioPacketBuffer.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+library std;
+use std.textio.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for TestRioPacketBuffer.
+-------------------------------------------------------------------------------
+entity TestRioPacketBuffer is
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for TestRioPacketBuffer.
+-------------------------------------------------------------------------------
+architecture TestRioPacketBufferImpl of TestRioPacketBuffer is
+
+ component RioPacketBufferWindow is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ inboundWriteFrameFull_o : out std_logic;
+ inboundWriteFrame_i : in std_logic;
+ inboundWriteFrameAbort_i : in std_logic;
+ inboundWriteContent_i : in std_logic;
+ inboundWriteContentData_i : in std_logic_vector(31 downto 0);
+ inboundReadFrameEmpty_o : out std_logic;
+ inboundReadFrame_i : in std_logic;
+ inboundReadFrameRestart_i : in std_logic;
+ inboundReadFrameAborted_o : out std_logic;
+ inboundReadContentEmpty_o : out std_logic;
+ inboundReadContent_i : in std_logic;
+ inboundReadContentEnd_o : out std_logic;
+ inboundReadContentData_o : out std_logic_vector(31 downto 0);
+
+ outboundWriteFrameFull_o : out std_logic;
+ outboundWriteFrame_i : in std_logic;
+ outboundWriteFrameAbort_i : in std_logic;
+ outboundWriteContent_i : in std_logic;
+ outboundWriteContentData_i : in std_logic_vector(31 downto 0);
+ outboundReadFrameEmpty_o : out std_logic;
+ outboundReadFrame_i : in std_logic;
+ outboundReadFrameRestart_i : in std_logic;
+ outboundReadFrameAborted_o : out std_logic;
+ outboundReadWindowEmpty_o : out std_logic;
+ outboundReadWindowReset_i : in std_logic;
+ outboundReadWindowNext_i : in std_logic;
+ outboundReadContentEmpty_o : out std_logic;
+ outboundReadContent_i : in std_logic;
+ outboundReadContentEnd_o : out std_logic;
+ outboundReadContentData_o : out std_logic_vector(31 downto 0));
+ end component;
+
+ signal clk : std_logic;
+ signal areset_n : std_logic;
+
+ signal inboundWriteFrameFull : std_logic;
+ signal inboundWriteFrame : std_logic;
+ signal inboundWriteFrameAbort : std_logic;
+ signal inboundWriteContent : std_logic;
+ signal inboundWriteContentData : std_logic_vector(31 downto 0);
+ signal inboundReadFrameEmpty : std_logic;
+ signal inboundReadFrame : std_logic;
+ signal inboundReadFrameRestart : std_logic;
+ signal inboundReadFrameAborted : std_logic;
+ signal inboundReadContentEmpty : std_logic;
+ signal inboundReadContent : std_logic;
+ signal inboundReadContentEnd : std_logic;
+ signal inboundReadContentData : std_logic_vector(31 downto 0);
+
+ signal outboundWriteFrameFull : std_logic;
+ signal outboundWriteFrame : std_logic;
+ signal outboundWriteFrameAbort : std_logic;
+ signal outboundWriteContent : std_logic;
+ signal outboundWriteContentData : std_logic_vector(31 downto 0);
+ signal outboundReadFrameEmpty : std_logic;
+ signal outboundReadFrame : std_logic;
+ signal outboundReadFrameRestart : std_logic;
+ signal outboundReadFrameAborted : std_logic;
+ signal outboundReadWindowEmpty : std_logic;
+ signal outboundReadWindowReset : std_logic;
+ signal outboundReadWindowNext : std_logic;
+ signal outboundReadContentEmpty : std_logic;
+ signal outboundReadContent : std_logic;
+ signal outboundReadContentEnd : std_logic;
+ signal outboundReadContentData : std_logic_vector(31 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Clock generation.
+ -----------------------------------------------------------------------------
+ ClockGenerator: process
+ begin
+ clk <= '0';
+ wait for 20 ns;
+ clk <= '1';
+ wait for 20 ns;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Test case driver.
+ -----------------------------------------------------------------------------
+ TestDriver: process
+ ---------------------------------------------------------------------------
+ -- Inbound procedures.
+ ---------------------------------------------------------------------------
+
+ procedure SetInboundWriteContent(
+ constant content : in std_logic_vector(31 downto 0)) is
+ begin
+ assert inboundWriteFrameFull = '0'
+ report "Inbound frame cannot be accepted." severity error;
+
+ inboundWriteContent <= '1';
+ inboundWriteContentData <= content;
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+ inboundWriteContent <= '0';
+ inboundWriteContentData <= (others=>'U');
+ end procedure;
+
+ procedure SetInboundWriteFrame is
+ begin
+ inboundWriteFrame <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ inboundWriteFrame <= '0';
+ end procedure;
+
+ procedure SetInboundWriteFrameAbort is
+ begin
+ inboundWriteFrameAbort <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ inboundWriteFrameAbort <= '0';
+ end procedure;
+
+ procedure SetInboundReadContent(
+ constant content : in std_logic_vector(31 downto 0)) is
+ begin
+ inboundReadContent <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ assert (inboundReadContentData = content)
+ report "Unexpected content read." severity error;
+ assert (inboundReadContentEnd = '0')
+ report "Unexpected content end." severity error;
+
+ inboundReadContent <= '0';
+ end procedure;
+
+ procedure SetInboundReadContentEnd is
+ begin
+ inboundReadContent <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ assert (inboundReadContentEnd = '1')
+ report "Unexpected content end." severity error;
+
+ inboundReadContent <= '0';
+ end procedure;
+
+ procedure SetInboundReadFrame is
+ begin
+ assert inboundReadFrameEmpty = '0'
+ report "No pending inbound frame to be read." severity error;
+
+ inboundReadFrame <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ inboundReadFrame <= '0';
+ end procedure;
+
+ procedure SetInboundReadFrameRestart is
+ begin
+ inboundReadFrameRestart <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ inboundReadFrameRestart <= '0';
+ end procedure;
+
+ ---------------------------------------------------------------------------
+ -- Outbound procedures.
+ ---------------------------------------------------------------------------
+
+ procedure SetOutboundWriteContent(
+ constant content : in std_logic_vector(31 downto 0)) is
+ begin
+ assert outboundWriteFrameFull = '0'
+ report "Outbound frame cannot be accepted." severity error;
+
+ outboundWriteContent <= '1';
+ outboundWriteContentData <= content;
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+ outboundWriteContent <= '0';
+ outboundWriteContentData <= (others=>'U');
+ end procedure;
+
+ procedure SetOutboundWriteFrame is
+ begin
+ assert outboundWriteFrameFull = '0'
+ report "Outbound frame cannot be accepted." severity error;
+
+ outboundWriteFrame <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundWriteFrame <= '0';
+ end procedure;
+
+ procedure SetOutboundWriteFrameAbort is
+ begin
+ outboundWriteFrameAbort <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundWriteFrameAbort <= '0';
+ end procedure;
+
+ procedure SetOutboundReadContent(
+ constant content : in std_logic_vector(31 downto 0)) is
+ begin
+ outboundReadContent <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ assert (outboundReadContentData = content)
+ report "Unexpected content read." severity error;
+ assert (outboundReadContentEnd = '0')
+ report "Unexpected content end." severity error;
+
+ outboundReadContent <= '0';
+ end procedure;
+
+ procedure SetOutboundReadContentEnd is
+ begin
+ outboundReadContent <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ assert (outboundReadContentEnd = '1')
+ report "Unexpected content end." severity error;
+
+ outboundReadContent <= '0';
+ end procedure;
+
+ procedure SetOutboundReadFrame is
+ begin
+ assert outboundReadFrameEmpty = '0'
+ report "No pending outbound frame to be read." severity error;
+
+ outboundReadFrame <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundReadFrame <= '0';
+ end procedure;
+
+ procedure SetOutboundReadFrameRestart is
+ begin
+ outboundReadFrameRestart <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundReadFrameRestart <= '0';
+ end procedure;
+
+ procedure SetOutboundReadWindowReset is
+ begin
+ outboundReadWindowReset <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundReadWindowReset <= '0';
+ end procedure;
+
+ procedure SetOutboundReadWindowNext is
+ begin
+ assert outboundReadWindowEmpty = '0'
+ report "No pending outbound window frame to be read." severity error;
+
+ outboundReadWindowNext <= '1';
+ wait until clk'event and clk = '1';
+ wait for 1 ns;
+
+ outboundReadWindowNext <= '0';
+ end procedure;
+
+ begin
+ inboundWriteFrame <= '0';
+ inboundWriteFrameAbort <= '0';
+ inboundWriteContent <= '0';
+ inboundWriteContentData <= (others=>'U');
+ inboundReadFrame <= '0';
+ inboundReadFrameRestart <= '0';
+ inboundReadContent <= '0';
+
+ outboundWriteFrame <= '0';
+ outboundWriteFrameAbort <= '0';
+ outboundWriteContent <= '0';
+ outboundWriteContentData <= (others=>'U');
+ outboundReadFrame <= '0';
+ outboundReadFrameRestart <= '0';
+ outboundReadWindowReset <= '0';
+ outboundReadWindowNext <= '0';
+ outboundReadContent <= '0';
+
+ areset_n <= '0';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+ areset_n <= '1';
+ wait until clk'event and clk = '1';
+ wait until clk'event and clk = '1';
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer-TC1");
+ PrintS("Description: Test normal operation without using the window. Only");
+ PrintS(" full frames are tested.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Complete a small frame and read it.");
+ PrintS("Result: The read frame should be equal to the one written.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC1-Step1");
+ ---------------------------------------------------------------------------
+ -- REMARK: Update testcases for inbound and outbound...
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundWriteContent(x"deadbeef");
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundWriteFrame;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundReadContent(x"deadbeef");
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundReadContentEnd;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundReadFrame;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Write a rio maximum size frame and read it.");
+ PrintS("Result: The read frame should be equal to the one written.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC1-Step2");
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 68 loop
+ SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundWriteFrame;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ for i in 0 to 68 loop
+ SetInboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundReadContentEnd;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundReadFrame;
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Fill the maximum number of small frames without filling ");
+ PrintS(" the memory.");
+ PrintS("Result: The frame buffer should accept 63 frames.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC1-Step3");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Write maximum number of frames.
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 2 loop
+ SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ for j in 1 to 62 loop
+ SetInboundWriteFrame;
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetInboundWriteContent(std_logic_vector(to_unsigned(j+i, 32)));
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+ end loop;
+
+ SetInboundWriteFrame;
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Read the frames written in the above steps.
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 2 loop
+ SetInboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundReadContentEnd;
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ for j in 1 to 62 loop
+ SetInboundReadFrame;
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetInboundReadContent(std_logic_vector(to_unsigned(j+i, 32)));
+
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundReadContentEnd;
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundReadFrame;
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Fill the memory to its limit.");
+ PrintS("Result: The frame buffer should accept 255-69 words.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC1-Step4");
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 186 loop
+ SetInboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundWriteFrame;
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 186 loop
+ SetInboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ end loop;
+
+ SetInboundReadContentEnd;
+ assert (inboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+
+ SetInboundReadFrame;
+ assert (inboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (inboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer-TC2");
+ PrintS("Description: Test operation when using the window.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Add one frame and update the window.");
+ PrintS("Result: The window empty flag and the read frame empty flag should");
+ PrintS(" be updated and it should be possible to read the frame again.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step1");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Add two frames and test the window accesses.");
+ PrintS("Result: .");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step2");
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Write two frames.
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(2+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Read the frames using the window mechanism.
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Reset the window and read the frames again.
+ ---------------------------------------------------------------------------
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Remove one frame and access the remaining frame.
+ ---------------------------------------------------------------------------
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(2+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Remove the remaining frame.
+ ---------------------------------------------------------------------------
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Add maximum number of frames and test the window accesses.");
+ PrintS("Result: The buffer should be full and not accept more frames.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step3");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Write 3*63 frames => maximum number of frames.
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 2 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for j in 1 to 62 loop
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Read the whole window until it is empty.
+ ---------------------------------------------------------------------------
+
+ for j in 0 to 61 loop
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(j+i, 32)));
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(62+i, 32)));
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Reset the window and remove all frames.
+ ---------------------------------------------------------------------------
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for j in 0 to 61 loop
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 2 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(62+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 4:");
+ PrintS("Action: Add maximum number of words and test the window accesses.");
+ PrintS("Result: The content memory should be full.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step4");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Write 6*31+69=255 words and 7 frames => full content.
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 30 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for j in 1 to 5 loop
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 30 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 68 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1024+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Read the whole window until it is empty.
+ ---------------------------------------------------------------------------
+
+ for j in 0 to 5 loop
+ for i in 0 to 30 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(j+i, 32)));
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for i in 0 to 68 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1024+i, 32)));
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Reset the window and remove all frames.
+ ---------------------------------------------------------------------------
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for j in 0 to 1 loop
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for j in 2 to 5 loop
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 68 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1024+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 5:");
+ PrintS("Action: Add maximum number of words -1 and test the window accesses.");
+ PrintS("Result: The content memory should not accept more frames.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step5");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Write 11*17=187 (one full frame will not fit).
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 16 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ for j in 1 to 10 loop
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 16 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(j+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Reset the window and remove all frames.
+ ---------------------------------------------------------------------------
+
+ SetOutboundReadWindowReset;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '1')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for j in 1 to 9 loop
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 6:");
+ PrintS("Action: Add two frames and start reading the second, then remove");
+ PrintS(" the first.");
+ PrintS("Result: The readContentEnd flag should not be changed when frames");
+ PrintS(" are removed.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC2-Step6");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i+1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 3 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(3, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(4, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer-TC3");
+ PrintS("Description: Test operation when restarting and aborting frames.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Write one frame and abort it.");
+ PrintS("Result: The aborted frame should be discarded.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC3-Step1");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrameAbort;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Write one full frame then one more that is aborted.");
+ PrintS("Result: The first frame should remain and the aborted should be ");
+ PrintS(" discarded.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC3-Step2");
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(2+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrameAbort;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(3+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(3+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Write one full frame then read one that is restarted.");
+ PrintS("Result: The content of the first frame should be read twice. ");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC3-Step3");
+ ---------------------------------------------------------------------------
+
+ for i in 0 to 3 loop
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrameRestart;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ for i in 0 to 3 loop
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1+i, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ end loop;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("TG_RioPacketBuffer-TC4");
+ PrintS("Description: Test operation when partial frames are read.");
+ PrintS("Requirement: XXXXX");
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 1:");
+ PrintS("Action: Write a one word frame and read it before it is completed.");
+ PrintS("Result: Empty signals should reflect the status of the frame.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC4-Step1");
+ ---------------------------------------------------------------------------
+
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 2:");
+ PrintS("Action: Write content to a frame and read it, then abort the frame.");
+ PrintS("Result: The reader should be notified about the aborted frame. The");
+ PrintS(" notification should be reset when the frame has been ");
+ PrintS(" restarted.");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC4-Step2");
+ ---------------------------------------------------------------------------
+
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteFrameAbort;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '1')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(2, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '1')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadFrameRestart;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(2, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ ---------------------------------------------------------------------------
+ PrintS("-----------------------------------------------------------------");
+ PrintS("Step 3:");
+ PrintS("Action: Write one complete frame then abort a second.");
+ PrintS("Result: The reader should not notice the aborted frame. ");
+ ---------------------------------------------------------------------------
+ PrintR("TG_RioPacketBuffer-TC4-Step3");
+ ---------------------------------------------------------------------------
+
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadContent(std_logic_vector(to_unsigned(1, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteContent(std_logic_vector(to_unsigned(2, 32)));
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundWriteFrameAbort;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadContentEnd;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '0')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '0')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadWindowNext;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '0')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ SetOutboundReadFrame;
+ assert (outboundWriteFrameFull = '0')
+ report "Unexpected writeFrameFull." severity error;
+ assert (outboundReadFrameEmpty = '1')
+ report "Unexpected readFrameEmpty." severity error;
+ assert (outboundReadWindowEmpty = '1')
+ report "Unexpected readWindowEmpty." severity error;
+ assert (outboundReadContentEmpty = '1')
+ report "Unexpected readContentEmpty." severity error;
+ assert (outboundReadFrameAborted = '0')
+ report "Unexpected readFrameAborted." severity error;
+
+ ---------------------------------------------------------------------------
+ -- Test completed.
+ ---------------------------------------------------------------------------
+
+ TestEnd;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Instantiate the testobject.
+ -----------------------------------------------------------------------------
+
+ TestPacketBuffer: RioPacketBufferWindow
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ inboundWriteFrameFull_o=>inboundWriteFrameFull,
+ inboundWriteFrame_i=>inboundWriteFrame,
+ inboundWriteFrameAbort_i=>inboundWriteFrameAbort,
+ inboundWriteContent_i=>inboundWriteContent,
+ inboundWriteContentData_i=>inboundWriteContentData,
+ inboundReadFrameEmpty_o=>inboundReadFrameEmpty,
+ inboundReadFrame_i=>inboundReadFrame,
+ inboundReadFrameRestart_i=>inboundReadFrameRestart,
+ inboundReadFrameAborted_o=>inboundReadFrameAborted,
+ inboundReadContentEmpty_o=>inboundReadContentEmpty,
+ inboundReadContent_i=>inboundReadContent,
+ inboundReadContentEnd_o=>inboundReadContentEnd,
+ inboundReadContentData_o=>inboundReadContentData,
+ outboundWriteFrameFull_o=>outboundWriteFrameFull,
+ outboundWriteFrame_i=>outboundWriteFrame,
+ outboundWriteFrameAbort_i=>outboundWriteFrameAbort,
+ outboundWriteContent_i=>outboundWriteContent,
+ outboundWriteContentData_i=>outboundWriteContentData,
+ outboundReadFrameEmpty_o=>outboundReadFrameEmpty,
+ outboundReadFrame_i=>outboundReadFrame,
+ outboundReadFrameRestart_i=>outboundReadFrameRestart,
+ outboundReadFrameAborted_o=>outboundReadFrameAborted,
+ outboundReadWindowEmpty_o=>outboundReadWindowEmpty,
+ outboundReadWindowReset_i=>outboundReadWindowReset,
+ outboundReadWindowNext_i=>outboundReadWindowNext,
+ outboundReadContentEmpty_o=>outboundReadContentEmpty,
+ outboundReadContent_i=>outboundReadContent,
+ outboundReadContentEnd_o=>outboundReadContentEnd,
+ outboundReadContentData_o=>outboundReadContentData);
+
+end architecture;
tags/1.0.2-release/bench/vhdl/TestRioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/RioSwitch.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioSwitch.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioSwitch.vhd (revision 50)
@@ -0,0 +1,2473 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing RapidIO packet switching functionality contained in the top
+-- entity RioSwitch.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioSwitch
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+-------------------------------------------------------------------------------
+-- Entity for RioSwitch.
+-------------------------------------------------------------------------------
+entity RioSwitch is
+ generic(
+ SWITCH_PORTS : natural range 3 to 255 := 4;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_i : in Array1(SWITCH_PORTS-1 downto 0);
+ writeFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeFrameAbort_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ writeContentData_o : out Array32(SWITCH_PORTS-1 downto 0);
+
+ readFrameEmpty_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readFrame_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readContent_o : out Array1(SWITCH_PORTS-1 downto 0);
+ readContentEnd_i : in Array1(SWITCH_PORTS-1 downto 0);
+ readContentData_i : in Array32(SWITCH_PORTS-1 downto 0);
+
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSwitch.
+-------------------------------------------------------------------------------
+architecture RioSwitchImpl of RioSwitch is
+
+ component RouteTableInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ stb_i : in Array1(WIDTH-1 downto 0);
+ addr_i : in Array16(WIDTH-1 downto 0);
+ dataM_o : out Array8(WIDTH-1 downto 0);
+ ack_o : out Array1(WIDTH-1 downto 0);
+
+ stb_o : out std_logic;
+ addr_o : out std_logic_vector(15 downto 0);
+ dataS_i : in std_logic_vector(7 downto 0);
+ ack_i : in std_logic);
+ end component;
+
+ component SwitchPortInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_i : in Array1(WIDTH-1 downto 0);
+ masterStb_i : in Array1(WIDTH-1 downto 0);
+ masterWe_i : in Array1(WIDTH-1 downto 0);
+ masterAddr_i : in Array10(WIDTH-1 downto 0);
+ masterData_i : in Array32(WIDTH-1 downto 0);
+ masterData_o : out Array1(WIDTH-1 downto 0);
+ masterAck_o : out Array1(WIDTH-1 downto 0);
+
+ slaveCyc_o : out Array1(WIDTH-1 downto 0);
+ slaveStb_o : out Array1(WIDTH-1 downto 0);
+ slaveWe_o : out Array1(WIDTH-1 downto 0);
+ slaveAddr_o : out Array10(WIDTH-1 downto 0);
+ slaveData_o : out Array32(WIDTH-1 downto 0);
+ slaveData_i : in Array1(WIDTH-1 downto 0);
+ slaveAck_i : in Array1(WIDTH-1 downto 0));
+ end component;
+
+ component SwitchPortMaintenance is
+ generic(
+ SWITCH_PORTS : natural range 0 to 255;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ lookupStb_i : in std_logic;
+ lookupAddr_i : in std_logic_vector(15 downto 0);
+ lookupData_o : out std_logic_vector(7 downto 0);
+ lookupAck_o : out std_logic;
+
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component SwitchPort is
+ generic(
+ PORT_INDEX : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+ end component;
+
+ signal masterLookupStb : Array1(SWITCH_PORTS downto 0);
+ signal masterLookupAddr : Array16(SWITCH_PORTS downto 0);
+ signal masterLookupData : Array8(SWITCH_PORTS downto 0);
+ signal masterLookupAck : Array1(SWITCH_PORTS downto 0);
+
+ signal slaveLookupStb : std_logic;
+ signal slaveLookupAddr : std_logic_vector(15 downto 0);
+ signal slaveLookupData : std_logic_vector(7 downto 0);
+ signal slaveLookupAck : std_logic;
+
+ signal masterCyc : Array1(SWITCH_PORTS downto 0);
+ signal masterStb : Array1(SWITCH_PORTS downto 0);
+ signal masterWe : Array1(SWITCH_PORTS downto 0);
+ signal masterAddr : Array10(SWITCH_PORTS downto 0);
+ signal masterDataWrite : Array32(SWITCH_PORTS downto 0);
+ signal masterDataRead : Array1(SWITCH_PORTS downto 0);
+ signal masterAck : Array1(SWITCH_PORTS downto 0);
+
+ signal slaveCyc : Array1(SWITCH_PORTS downto 0);
+ signal slaveStb : Array1(SWITCH_PORTS downto 0);
+ signal slaveWe : Array1(SWITCH_PORTS downto 0);
+ signal slaveAddr : Array10(SWITCH_PORTS downto 0);
+ signal slaveDataWrite : Array32(SWITCH_PORTS downto 0);
+ signal slaveDataRead : Array1(SWITCH_PORTS downto 0);
+ signal slaveAck : Array1(SWITCH_PORTS downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- The routing table interconnect.
+ -----------------------------------------------------------------------------
+ RouteInterconnect: RouteTableInterconnect
+ generic map(
+ WIDTH=>SWITCH_PORTS+1)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ stb_i=>masterLookupStb, addr_i=>masterLookupAddr,
+ dataM_o=>masterLookupData, ack_o=>masterLookupAck,
+ stb_o=>slaveLookupStb, addr_o=>slaveLookupAddr,
+ dataS_i=>slaveLookupData, ack_i=>slaveLookupAck);
+
+ -----------------------------------------------------------------------------
+ -- The port interconnect.
+ -----------------------------------------------------------------------------
+ PortInterconnect: SwitchPortInterconnect
+ generic map(
+ WIDTH=>SWITCH_PORTS+1)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ masterCyc_i=>masterCyc, masterStb_i=>masterStb, masterWe_i=>masterWe, masterAddr_i=>masterAddr,
+ masterData_i=>masterDataWrite, masterData_o=>masterDataRead, masterAck_o=>masterAck,
+ slaveCyc_o=>slaveCyc, slaveStb_o=>slaveStb, slaveWe_o=>slaveWe, slaveAddr_o=>slaveAddr,
+ slaveData_o=>slaveDataWrite, slaveData_i=>slaveDataRead, slaveAck_i=>slaveAck);
+
+ -----------------------------------------------------------------------------
+ -- Data relaying port instantiation.
+ -----------------------------------------------------------------------------
+ PortGeneration: for portIndex in 0 to SWITCH_PORTS-1 generate
+ PortInst: SwitchPort
+ generic map(
+ PORT_INDEX=>portIndex)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ masterCyc_o=>masterCyc(portIndex), masterStb_o=>masterStb(portIndex),
+ masterWe_o=>masterWe(portIndex), masterAddr_o=>masterAddr(portIndex),
+ masterData_o=>masterDataWrite(portIndex),
+ masterData_i=>masterDataRead(portIndex), masterAck_i=>masterAck(portIndex),
+ slaveCyc_i=>slaveCyc(portIndex), slaveStb_i=>slaveStb(portIndex),
+ slaveWe_i=>slaveWe(portIndex), slaveAddr_i=>slaveAddr(portIndex),
+ slaveData_i=>slaveDataWrite(portIndex),
+ slaveData_o=>slaveDataRead(portIndex), slaveAck_o=>slaveAck(portIndex),
+ lookupStb_o=>masterLookupStb(portIndex),
+ lookupAddr_o=>masterLookupAddr(portIndex),
+ lookupData_i=>masterLookupData(portIndex), lookupAck_i=>masterLookupAck(portIndex),
+ readFrameEmpty_i=>readFrameEmpty_i(portIndex), readFrame_o=>readFrame_o(portIndex),
+ readContent_o=>readContent_o(portIndex),
+ readContentEnd_i=>readContentEnd_i(portIndex), readContentData_i=>readContentData_i(portIndex),
+ writeFrameFull_i=>writeFrameFull_i(portIndex), writeFrame_o=>writeFrame_o(portIndex),
+ writeFrameAbort_o=>writeFrameAbort_o(portIndex), writeContent_o=>writeContent_o(portIndex),
+ writeContentData_o=>writeContentData_o(portIndex));
+ end generate;
+
+ -----------------------------------------------------------------------------
+ -- Maintenance port instantiation.
+ -----------------------------------------------------------------------------
+ MaintenancePort: SwitchPortMaintenance
+ generic map(
+ SWITCH_PORTS=>SWITCH_PORTS,
+ DEVICE_IDENTITY=>DEVICE_IDENTITY,
+ DEVICE_VENDOR_IDENTITY=>DEVICE_VENDOR_IDENTITY,
+ DEVICE_REV=>DEVICE_REV,
+ ASSY_IDENTITY=>ASSY_IDENTITY,
+ ASSY_VENDOR_IDENTITY=>ASSY_VENDOR_IDENTITY,
+ ASSY_REV=>ASSY_REV)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ lookupStb_i=>slaveLookupStb, lookupAddr_i=>slaveLookupAddr,
+ lookupData_o=>slaveLookupData, lookupAck_o=>slaveLookupAck,
+ masterCyc_o=>masterCyc(SWITCH_PORTS), masterStb_o=>masterStb(SWITCH_PORTS),
+ masterWe_o=>masterWe(SWITCH_PORTS), masterAddr_o=>masterAddr(SWITCH_PORTS),
+ masterData_o=>masterDataWrite(SWITCH_PORTS),
+ masterData_i=>masterDataRead(SWITCH_PORTS), masterAck_i=>masterAck(SWITCH_PORTS),
+ slaveCyc_i=>slaveCyc(SWITCH_PORTS), slaveStb_i=>slaveStb(SWITCH_PORTS),
+ slaveWe_i=>slaveWe(SWITCH_PORTS), slaveAddr_i=>slaveAddr(SWITCH_PORTS),
+ slaveData_i=>slaveDataWrite(SWITCH_PORTS),
+ slaveData_o=>slaveDataRead(SWITCH_PORTS), slaveAck_o=>slaveAck(SWITCH_PORTS),
+ lookupStb_o=>masterLookupStb(SWITCH_PORTS),
+ lookupAddr_o=>masterLookupAddr(SWITCH_PORTS),
+ lookupData_i=>masterLookupData(SWITCH_PORTS), lookupAck_i=>masterLookupAck(SWITCH_PORTS),
+ portLinkTimeout_o=>portLinkTimeout_o,
+ linkInitialized_i=>linkInitialized_i,
+ outputPortEnable_o=>outputPortEnable_o, inputPortEnable_o=>inputPortEnable_o,
+ localAckIdWrite_o=>localAckIdWrite_o, clrOutstandingAckId_o=>clrOutstandingAckId_o,
+ inboundAckId_o=>inboundAckId_o, outstandingAckId_o=>outstandingAckId_o,
+ outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i,
+ outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i,
+ configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o,
+ configData_o=>configData_o, configData_i=>configData_i);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- SwitchPort
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for SwitchPort.
+-------------------------------------------------------------------------------
+entity SwitchPort is
+ generic(
+ PORT_INDEX : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Master port signals.
+ -- Write frames to other ports.
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ -- Slave port signals.
+ -- Receives frames from other ports.
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ -- Address-lookup interface.
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ -- Physical port frame buffer interface.
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for SwitchPort.
+-------------------------------------------------------------------------------
+architecture SwitchPortImpl of SwitchPort is
+
+ type MasterStateType is (STATE_IDLE,
+ STATE_ERROR,
+ STATE_WAIT_HEADER_0,
+ STATE_READ_HEADER_0,
+ STATE_READ_PORT_LOOKUP,
+ STATE_READ_TARGET_PORT,
+ STATE_WAIT_TARGET_PORT,
+ STATE_WAIT_TARGET_WRITE,
+ STATE_WAIT_COMPLETE);
+ signal masterState : MasterStateType;
+
+ type SlaveStateType is (STATE_IDLE, STATE_SEND_ACK);
+ signal slaveState : SlaveStateType;
+
+ alias ftype : std_logic_vector(3 downto 0) is readContentData_i(19 downto 16);
+ alias tt : std_logic_vector(1 downto 0) is readContentData_i(21 downto 20);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Master interface process.
+ -----------------------------------------------------------------------------
+ Master: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ masterState <= STATE_IDLE;
+
+ lookupStb_o <= '0';
+ lookupAddr_o <= (others => '0');
+
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterWe_o <= '0';
+ masterAddr_o <= (others => '0');
+ masterData_o <= (others => '0');
+
+ readContent_o <= '0';
+ readFrame_o <= '0';
+ elsif (clk'event and clk = '1') then
+ readContent_o <= '0';
+ readFrame_o <= '0';
+
+ case masterState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for a new packet or content of a new packet.
+ ---------------------------------------------------------------------
+
+ -- Reset bus signals.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+
+ -- Wait for frame content to be available.
+ -- Use different signals to trigger the forwarding of packets depending
+ -- on the switch philosofy.
+ if (readFrameEmpty_i = '0') then
+ readContent_o <= '1';
+ masterState <= STATE_WAIT_HEADER_0;
+ end if;
+
+ when STATE_WAIT_HEADER_0 =>
+ ---------------------------------------------------------------------
+ -- Wait for the frame buffer output to be updated.
+ ---------------------------------------------------------------------
+
+ -- Wait for frame buffer output to be updated.
+ masterState <= STATE_READ_HEADER_0;
+
+ when STATE_READ_HEADER_0 =>
+ ---------------------------------------------------------------------
+ -- Check the FTYPE and forward it to the maintenance port if it is a
+ -- maintenance packet. Otherwise, initiate an address lookup and wait
+ -- for the result.
+ ---------------------------------------------------------------------
+
+ -- Check if the frame has ended.
+ if (readContentEnd_i = '0') then
+ -- The frame has not ended.
+ -- This word contains the header and the source id.
+
+ -- Read the tt-field to check the source and destination id size.
+ if (tt = "01") then
+ -- This frame contains 16-bit addresses.
+
+ -- Read the new content.
+ readContent_o <= '1';
+
+ -- Save the content of the header and destination.
+ masterData_o <= readContentData_i;
+
+ -- Check if this is a maintenance frame.
+ if (ftype = FTYPE_MAINTENANCE_CLASS) then
+ -- This is a maintenance frame.
+
+ -- Always route these frames to the maintenance module in the
+ -- switch by setting the MSB bit of the port address.
+ masterAddr_o <= '1' & std_logic_vector(to_unsigned(PORT_INDEX, 8)) & '0';
+
+ -- Start an access to the maintenance port.
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- This is not a maintenance frame.
+
+ -- Lookup the destination address and proceed to wait for the
+ -- result.
+ lookupStb_o <= '1';
+ lookupAddr_o <= readContentData_i(15 downto 0);
+
+ -- Wait for the port lookup to return a result.
+ masterState <= STATE_READ_PORT_LOOKUP;
+ end if;
+ else
+ -- Unsupported tt-value, discard the frame.
+ readFrame_o <= '1';
+ masterState <= STATE_ERROR;
+ end if;
+ else
+ -- End of frame.
+ -- The frame is too short to contain a valid frame. Discard it.
+ readFrame_o <= '1';
+ masterState <= STATE_ERROR;
+ end if;
+
+ when STATE_ERROR =>
+ ---------------------------------------------------------------------
+ -- Wait one tick for the packet buffer to update its outputs. Then
+ -- start waiting for a new packet.
+ ---------------------------------------------------------------------
+
+ masterState <= STATE_IDLE;
+
+ when STATE_READ_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ -- Wait for the address lookup to be complete.
+ ---------------------------------------------------------------------
+
+ -- Wait for the routing table to complete the request.
+ if (lookupAck_i = '1') then
+ -- The address lookup is complete.
+
+ -- Terminate the lookup cycle.
+ lookupStb_o <= '0';
+
+ -- Proceed to read the target port.
+ masterAddr_o <= '0' & lookupData_i & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- Wait until the address lookup is complete.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_READ_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ -- Initiate an access to the target port.
+ ---------------------------------------------------------------------
+
+ -- Read the status of the target port using the result from the
+ -- lookup in the routing table.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '0';
+ masterState <= STATE_WAIT_TARGET_PORT;
+
+ when STATE_WAIT_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ -- Wait to get access to the target port. When the port is ready
+ -- check if it is ready to accept a new frame. If it cannot accept a
+ -- new frame, terminate the access and go back and start a new one.
+ -- This is to free the interconnect to let other ports access it if
+ -- it is a shared bus. If the port is ready, initiate a write access
+ -- to the selected port.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ -- Target port has completed the request.
+
+ -- Check the status of the target port.
+ if (masterData_i = '0') then
+ -- The target port has empty buffers to receive the frame.
+
+ -- Hold the bus with cyc until the cycle is complete.
+ -- Write the first word of the frame to the target port.
+ -- The masterData_o has already been assigned.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '1';
+
+ -- Change state to transfer the frame.
+ masterState <= STATE_WAIT_TARGET_WRITE;
+ else
+ -- The target port has no empty buffer to receive the frame.
+ -- Terminate the cycle and retry later.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end if;
+ else
+ -- Target port has not completed the request.
+ -- Dont to anything.
+ end if;
+
+ when STATE_WAIT_TARGET_WRITE =>
+ ---------------------------------------------------------------------
+ -- Wait for the write access to complete. When complete, write the
+ -- next content and update the content to the next. If the frame does
+ -- not have any more data ready, terminate the access but keep the
+ -- cycle active and proceed to wait for new data.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ -- REMARK: Remove the ack-condition, we know that the write takes one
+ -- cycle...
+ if (masterAck_i = '1') then
+ -- The target port is ready.
+
+ -- Check if the frame has ended.
+ if (readContentEnd_i = '0') then
+ -- The frame has not ended.
+
+ -- There are more data to transfer.
+ masterData_o <= readContentData_i;
+ readContent_o <= '1';
+ else
+ -- There are no more data to transfer.
+
+ -- Update to the next frame.
+ readFrame_o <= '1';
+
+ -- Tell the target port that the frame is complete.
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '0';
+ masterData_o <= x"00000001";
+
+ -- Change state to wait for the target port to finalize the write
+ -- of the full frame.
+ masterState <= STATE_WAIT_COMPLETE;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- Dont do anything.
+ end if;
+
+ when STATE_WAIT_COMPLETE =>
+ ---------------------------------------------------------------------
+ -- Wait for the target port to signal that the frame has been
+ -- completed.
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the final request.
+ if (masterAck_i = '1') then
+ -- The target port has finalized the write of the frame.
+
+ -- Reset master bus signals.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_IDLE;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ end case;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Slave interface process.
+ -----------------------------------------------------------------------------
+ -- Addr | Read | Write
+ -- 0 | full | abort & complete
+ -- 1 | full | frameData
+ writeContentData_o <= slaveData_i;
+ Slave: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ slaveState <= STATE_IDLE;
+
+ slaveData_o <= '0';
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+ elsif (clk'event and clk = '1') then
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+
+ case slaveState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for an access from a master.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then
+ -- Cycle is active.
+
+ -- Check if the cycle is accessing the status- or data address.
+ if (slaveAddr_i(0) = '0') then
+ -- Accessing port status address.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing the status address.
+ -- Update the buffering output signals according to the input
+ -- data.
+ writeFrame_o <= slaveData_i(0);
+ writeFrameAbort_o <= slaveData_i(1);
+ else
+ -- Reading the status address.
+ slaveData_o <= writeFrameFull_i;
+ end if;
+ else
+ -- Accessing port data address.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Write frame content into the frame buffer.
+ writeContent_o <= '1';
+ else
+ slaveData_o <= writeFrameFull_i;
+ end if;
+ end if;
+
+ -- Change state to send an ack to the master.
+ slaveState <= STATE_SEND_ACK;
+ end if;
+
+ when STATE_SEND_ACK =>
+ ---------------------------------------------------------------------
+ -- Wait for acknowledge to be received by the master.
+ ---------------------------------------------------------------------
+
+ -- Go back to the idle state and wait for a new cycle.
+ slaveState <= STATE_IDLE;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+ -- Assign the acknowledge depending on the current slave state.
+ slaveAck_o <= '1' when (slaveState = STATE_SEND_ACK) else '0';
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- SwitchPortMaintenance
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for SwitchPortMaintenance.
+-------------------------------------------------------------------------------
+entity SwitchPortMaintenance is
+ generic(
+ SWITCH_PORTS : natural range 0 to 255;
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0));
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Routing table port lookup signals.
+ lookupStb_i : in std_logic;
+ lookupAddr_i : in std_logic_vector(15 downto 0);
+ lookupData_o : out std_logic_vector(7 downto 0);
+ lookupAck_o : out std_logic;
+
+ -- Master port signals.
+ -- Write frames to other ports.
+ masterCyc_o : out std_logic;
+ masterStb_o : out std_logic;
+ masterWe_o : out std_logic;
+ masterAddr_o : out std_logic_vector(9 downto 0);
+ masterData_o : out std_logic_vector(31 downto 0);
+ masterData_i : in std_logic;
+ masterAck_i : in std_logic;
+
+ -- Slave port signals.
+ -- Receives frames from other ports.
+ slaveCyc_i : in std_logic;
+ slaveStb_i : in std_logic;
+ slaveWe_i : in std_logic;
+ slaveAddr_i : in std_logic_vector(9 downto 0);
+ slaveData_i : in std_logic_vector(31 downto 0);
+ slaveData_o : out std_logic;
+ slaveAck_o : out std_logic;
+
+ -- Address-lookup interface.
+ lookupStb_o : out std_logic;
+ lookupAddr_o : out std_logic_vector(15 downto 0);
+ lookupData_i : in std_logic_vector(7 downto 0);
+ lookupAck_i : in std_logic;
+
+ -- Port common access interface.
+ portLinkTimeout_o : out std_logic_vector(23 downto 0);
+
+ -- Port specific access interface.
+ linkInitialized_i : in Array1(SWITCH_PORTS-1 downto 0);
+ outputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inputPortEnable_o : out Array1(SWITCH_PORTS-1 downto 0);
+ localAckIdWrite_o : out Array1(SWITCH_PORTS-1 downto 0);
+ clrOutstandingAckId_o : out Array1(SWITCH_PORTS-1 downto 0);
+ inboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_o : out Array5(SWITCH_PORTS-1 downto 0);
+ inboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outstandingAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+ outboundAckId_i : in Array5(SWITCH_PORTS-1 downto 0);
+
+ -- Configuration space for implementation-defined space.
+ configStb_o : out std_logic;
+ configWe_o : out std_logic;
+ configAddr_o : out std_logic_vector(23 downto 0);
+ configData_o : out std_logic_vector(31 downto 0);
+ configData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for SwitchPort.
+-------------------------------------------------------------------------------
+architecture SwitchPortMaintenanceImpl of SwitchPortMaintenance is
+
+ component MemoryDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ writeEnableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component MemorySinglePort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clk_i : in std_logic;
+ enable_i : in std_logic;
+ writeEnable_i : in std_logic;
+ address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+ end component;
+
+ type MasterStateType is (STATE_IDLE,
+ STATE_CHECK_FRAME,
+ STATE_RELAY_READ_RESPONSE,
+ STATE_RELAY_WRITE_RESPONSE,
+ STATE_SEND_READ_REQUEST,
+ STATE_SEND_WRITE_REQUEST,
+ STATE_SEND_READ_RESPONSE,
+ STATE_SEND_WRITE_RESPONSE,
+ STATE_START_PORT_LOOKUP,
+ STATE_READ_PORT_LOOKUP,
+ STATE_READ_TARGET_PORT,
+ STATE_WAIT_TARGET_PORT,
+ STATE_WAIT_TARGET_WRITE,
+ STATE_WAIT_COMPLETE,
+ STATE_WAIT_SLAVE);
+ signal masterState : MasterStateType;
+
+ signal crc16Data : std_logic_vector(31 downto 0);
+ signal crc16Current : std_logic_vector(15 downto 0);
+ signal crc16Temp : std_logic_vector(15 downto 0);
+ signal crc16Next : std_logic_vector(15 downto 0);
+
+ signal configEnable : std_logic;
+ signal configWrite : std_logic;
+ signal configAddress : std_logic_vector(23 downto 0);
+ signal configDataWrite : std_logic_vector(31 downto 0);
+ signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
+
+ signal outboundFrameEnable : std_logic;
+ signal outboundFrameWrite : std_logic;
+ signal outboundFrameAddress : std_logic_vector(2 downto 0);
+ signal outboundFrameDataWrite : std_logic_vector(31 downto 0);
+ signal outboundFrameDataRead : std_logic_vector(31 downto 0);
+ signal outboundFrameLength : std_logic_vector(2 downto 0);
+
+ type SlaveStateType is (STATE_READY,
+ STATE_BUSY);
+ signal slaveState : SlaveStateType;
+ signal slaveAck : std_logic;
+
+ signal inboundFrameReady : std_logic;
+ signal inboundFramePort : std_logic_vector(7 downto 0);
+ signal inboundFrameLength : natural range 0 to 7;
+ signal inboundFrameComplete : std_logic;
+
+ signal vc : std_logic;
+ signal crf : std_logic;
+ signal prio : std_logic_vector(1 downto 0);
+ signal tt : std_logic_vector(1 downto 0);
+ signal ftype : std_logic_vector(3 downto 0);
+ signal destinationId : std_logic_vector(15 downto 0);
+ signal sourceId : std_logic_vector(15 downto 0);
+ signal transaction : std_logic_vector(3 downto 0);
+ signal size : std_logic_vector(3 downto 0);
+ signal srcTid : std_logic_vector(7 downto 0);
+ signal hopCount : std_logic_vector(7 downto 0);
+ signal configOffset : std_logic_vector(20 downto 0);
+ signal wdptr : std_logic;
+ signal content : std_logic_vector(63 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Route table access signals.
+ -----------------------------------------------------------------------------
+
+ signal lookupEnable : std_logic;
+ signal lookupAddress : std_logic_vector(10 downto 0);
+ signal lookupData : std_logic_vector(7 downto 0);
+ signal lookupAck : std_logic;
+
+ signal routeTableEnable : std_logic;
+ signal routeTableWrite : std_logic;
+ signal routeTableAddress : std_logic_vector(10 downto 0);
+ signal routeTablePortWrite : std_logic_vector(7 downto 0);
+ signal routeTablePortRead : std_logic_vector(7 downto 0);
+
+ signal routeTablePortDefault : std_logic_vector(7 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Configuration space signals.
+ -----------------------------------------------------------------------------
+
+ signal discovered : std_logic;
+
+ signal hostBaseDeviceIdLocked : std_logic;
+ signal hostBaseDeviceId : std_logic_vector(15 downto 0);
+ signal componentTag : std_logic_vector(31 downto 0);
+
+ signal portLinkTimeout : std_logic_vector(23 downto 0);
+
+ signal outputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
+ signal inputPortEnable : Array1(SWITCH_PORTS-1 downto 0);
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Memory to contain the outbound frame.
+ -----------------------------------------------------------------------------
+
+ OutboundFrameMemory: MemorySinglePort
+ generic map(
+ ADDRESS_WIDTH=>3, DATA_WIDTH=>32)
+ port map(
+ clk_i=>clk,
+ enable_i=>outboundFrameEnable, writeEnable_i=>outboundFrameWrite,
+ address_i=>outboundFrameAddress,
+ data_i=>outboundFrameDataWrite, data_o=>outboundFrameDataRead);
+
+ -----------------------------------------------------------------------------
+ -- CRC generation for outbound frames.
+ -----------------------------------------------------------------------------
+
+ crc16Data <= outboundFrameDataWrite;
+
+ -- REMARK: Insert FFs here to make the critical path shorter...
+ Crc16High: Crc16CITT
+ port map(
+ d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
+ Crc16Low: Crc16CITT
+ port map(
+ d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
+
+ -----------------------------------------------------------------------------
+ -- Master interface process.
+ -----------------------------------------------------------------------------
+ Master: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ masterState <= STATE_IDLE;
+
+ lookupStb_o <= '0';
+ lookupAddr_o <= (others => '0');
+
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterWe_o <= '0';
+ masterAddr_o <= (others => '0');
+ masterData_o <= (others => '0');
+
+ configEnable <= '0';
+ configWrite <= '0';
+ configAddress <= (others => '0');
+ configDataWrite <= (others => '0');
+
+ outboundFrameEnable <= '0';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= (others=>'0');
+ outboundFrameLength <= (others=>'0');
+
+ inboundFrameComplete <= '0';
+ elsif (clk'event and clk = '1') then
+ configEnable <= '0';
+ configWrite <= '0';
+ inboundFrameComplete <= '0';
+
+ case masterState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for a full frame to be available.
+ if (inboundFrameReady = '1') then
+ if (inboundFrameLength > 3) then
+ masterState <= STATE_CHECK_FRAME;
+ else
+ -- Frame is too short.
+ -- REMARK: Discard the frame.
+ end if;
+ end if;
+
+ when STATE_CHECK_FRAME =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Check if the frame has 16-bit addresses and is a maintenance frame.
+ if (tt = "01") and (ftype = FTYPE_MAINTENANCE_CLASS) then
+ -- Maintenance class frame and 16-bit addresses.
+
+ -- Check the frame type.
+ case transaction is
+
+ when "0000" =>
+ ---------------------------------------------------------------
+ -- Maintenance read request.
+ ---------------------------------------------------------------
+
+ -- Check if the frame is for us.
+ if (hopCount = x"00") then
+ -- This frame is for us.
+ configEnable <= '1';
+ configWrite <= '0';
+ configAddress <= configOffset & wdptr & "00";
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_READ_RESPONSE;
+ else
+ -- This frame is not for us.
+ -- Decrement hop_count and relay.
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_READ_REQUEST;
+ end if;
+
+ when "0001" =>
+ ---------------------------------------------------------------
+ -- Maintenance write request.
+ ---------------------------------------------------------------
+
+ -- Check if the frame is for us.
+ if (hopCount = x"00") then
+ -- This frame is for us.
+ configEnable <= '1';
+ configWrite <= '1';
+ configAddress <= configOffset & wdptr & "00";
+
+ if (wdptr = '0') then
+ configDataWrite <= content(63 downto 32);
+ else
+ configDataWrite <= content(31 downto 0);
+ end if;
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & sourceId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_WRITE_RESPONSE;
+ else
+ -- This frame is not for us.
+ -- Decrement hop_count and relay.
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ masterState <= STATE_SEND_WRITE_REQUEST;
+ end if;
+
+ when "0010" =>
+ ---------------------------------------------------------------
+ -- Maintenance read response frame.
+ ---------------------------------------------------------------
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ -- Relay frame.
+ masterState <= STATE_RELAY_READ_RESPONSE;
+
+ when "0011" =>
+ ---------------------------------------------------------------
+ -- Maintenance write response frame.
+ ---------------------------------------------------------------
+
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameDataWrite <= "000000" & vc & crf & prio & tt & ftype & destinationId;
+ crc16Current <= x"ffff";
+
+ -- Relay frame.
+ masterState <= STATE_RELAY_WRITE_RESPONSE;
+
+ when "0100" =>
+ ---------------------------------------------------------------
+ -- Maintenance port write frame.
+ ---------------------------------------------------------------
+
+ -- REMARK: Support these???
+
+ when others =>
+ ---------------------------------------------------------------
+ -- Unsupported frame type.
+ ---------------------------------------------------------------
+
+ -- REMARK: Support these???
+ end case;
+ else
+ -- Non-maintenance class frame or unsupported address type.
+ -- REMARK: These should not end up here... discard them???
+ end if;
+
+ when STATE_RELAY_READ_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A maintenance response has been received. It should be relayed as
+ -- is using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(63 downto 32);
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(31 downto 0);
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_RELAY_WRITE_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A maintenance response has been received. It should be relayed as
+ -- is using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= hopCount & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_READ_REQUEST =>
+ ---------------------------------------------------------------------
+ -- A read request has been received but the hopcount is larger than
+ -- zero. Decrement the hopcount, recalculate the crc and relay the
+ -- frame using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_WRITE_REQUEST =>
+ ---------------------------------------------------------------------
+ -- A write request has been received but the hopcount is larger than
+ -- zero. Decrement the hopcount, recalculate the crc and relay the
+ -- frame using the destinationId.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= sourceId & transaction & size & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= std_logic_vector(unsigned(hopCount) - 1) & configOffset & wdptr & "00";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(63 downto 32);
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= content(31 downto 0);
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterState <= STATE_START_PORT_LOOKUP;
+ end case;
+
+ when STATE_SEND_READ_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A read request has been received with a hopcount that are zero.
+ -- Create a read response, calculate crc and write it to the port it
+ -- came from.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= destinationId & "0010" & "0000" & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= x"ff" & x"000000";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ if (wdptr = '1') then
+ outboundFrameDataWrite <= (others => '0');
+ else
+ outboundFrameDataWrite <= configDataRead(31 downto 0);
+ end if;
+ crc16Current <= crc16Next;
+ when 3 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ if (wdptr = '1') then
+ outboundFrameDataWrite <= configDataRead(31 downto 0);
+ else
+ outboundFrameDataWrite <= (others => '0');
+ end if;
+ crc16Current <= crc16Next;
+ when 4 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterAddr_o <= '0' & inboundFramePort & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end case;
+
+ when STATE_SEND_WRITE_RESPONSE =>
+ ---------------------------------------------------------------------
+ -- A write request has been received with a hopcount that are zero.
+ -- Create a write response, calculate crc and write it to the port it
+ -- came from.
+ ---------------------------------------------------------------------
+
+ case to_integer(unsigned(outboundFrameAddress)) is
+ when 0 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= destinationId & "0011" & "0000" & srcTid;
+ crc16Current <= crc16Next;
+ when 1 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite <= x"ff" & x"000000";
+ crc16Current <= crc16Next;
+ when 2 =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '1';
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ outboundFrameDataWrite(31 downto 16) <= crc16Next;
+ outboundFrameDataWrite(15 downto 0) <= x"0000";
+ when others =>
+ outboundFrameEnable <= '1';
+ outboundFrameWrite <= '0';
+ outboundFrameAddress <= (others=>'0');
+ outboundFrameLength <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ masterAddr_o <= '0' & inboundFramePort & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end case;
+
+ when STATE_START_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Initiate a port-lookup of the destination address.
+ lookupStb_o <= '1';
+ lookupAddr_o <= destinationId;
+ masterState <= STATE_READ_PORT_LOOKUP;
+
+ when STATE_READ_PORT_LOOKUP =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the routing table to complete the request.
+ if (lookupAck_i = '1') then
+ -- The address lookup is complete.
+
+ -- Terminate the lookup cycle.
+ lookupStb_o <= '0';
+
+ -- Wait for the target port to reply.
+ masterAddr_o <= '0' & lookupData_i & '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ else
+ -- Wait until the address lookup is complete.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_READ_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Read the status of the target port using the result from the
+ -- lookup in the routing table.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '0';
+ masterState <= STATE_WAIT_TARGET_PORT;
+
+ when STATE_WAIT_TARGET_PORT =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ if (masterData_i = '0') then
+ -- The target port has empty buffers to receive the frame.
+
+ -- Write the first word of the frame to the target port.
+ -- The masterData_o has already been assigned.
+ masterCyc_o <= '1';
+ masterStb_o <= '1';
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '1';
+
+ -- Read the first word in the frame and update the frame address.
+ masterData_o <= outboundFrameDataRead;
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+
+ -- Change state to transfer the frame.
+ masterState <= STATE_WAIT_TARGET_WRITE;
+ else
+ -- The target port has no empty buffer to receive the frame.
+ -- Terminate the cycle and retry later.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_READ_TARGET_PORT;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_TARGET_WRITE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the request.
+ if (masterAck_i = '1') then
+ -- The target port is ready.
+
+ -- Check if the frame has ended.
+ if (outboundFrameLength /= outboundFrameAddress) then
+ -- The frame has not ended.
+
+ -- There are more data to transfer.
+ masterData_o <= outboundFrameDataRead;
+ outboundFrameAddress <= std_logic_vector(unsigned(outboundFrameAddress) + 1);
+ else
+ -- There are no more data to transfer.
+
+ -- Tell the target port that the frame is complete.
+ masterWe_o <= '1';
+ masterAddr_o(0) <= '0';
+ masterData_o <= x"00000001";
+ outboundFrameAddress <= (others=>'0');
+
+ -- Change state to wait for the target port to finalize the write
+ -- of the full frame.
+ masterState <= STATE_WAIT_COMPLETE;
+ end if;
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_COMPLETE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+
+ -- Wait for the target port to complete the final request.
+ if (masterAck_i = '1') then
+ -- The target port has finalized the write of the frame.
+ masterCyc_o <= '0';
+ masterStb_o <= '0';
+ masterState <= STATE_WAIT_SLAVE;
+
+ -- Indicate the frame has been read.
+ inboundFrameComplete <= '1';
+ else
+ -- Wait for the target port to reply.
+ -- REMARK: Timeout here???
+ end if;
+
+ when STATE_WAIT_SLAVE =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ masterState <= STATE_IDLE;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ end case;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Slave interface process.
+ -----------------------------------------------------------------------------
+ -- Addr | Read | Write
+ -- 0 | full | abort & complete
+ -- 1 | full | frameData
+ Slave: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ slaveState <= STATE_READY;
+ slaveData_o <= '0';
+ slaveAck <= '0';
+
+ vc <= '0';
+ crf <= '0';
+ prio <= (others=>'0');
+ tt <= (others=>'0');
+ ftype <= (others=>'0');
+ destinationId <= (others=>'0');
+ sourceId <= (others=>'0');
+ transaction <= (others=>'0');
+ size <= (others=>'0');
+ srcTid <= (others=>'0');
+ hopCount <= (others=>'0');
+ configOffset <= (others=>'0');
+ wdptr <= '0';
+ content <= (others=>'0');
+
+ inboundFrameReady <= '0';
+ inboundFramePort <= (others => '0');
+ inboundFrameLength <= 0;
+ elsif (clk'event and clk = '1') then
+ slaveAck <= '0';
+
+ case slaveState is
+ when STATE_READY =>
+ ---------------------------------------------------------------------
+ -- Ready to receive a new frame.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
+ -- Cycle is active.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing request.
+
+ -- Check if the cycle is accessing the status- or data address.
+ if (slaveAddr_i(0) = '0') then
+ -- Writing to port status address.
+
+ if (slaveData_i(0) = '1') and (slaveData_i(1) = '0') then
+ -- A frame has been written.
+
+ -- Indicate the frame is ready for processing.
+ -- The slave address contains the number of the accessing port.
+ inboundFrameReady <= '1';
+ inboundFramePort <= slaveAddr_i(8 downto 1);
+
+ -- Change state until the frame has been processed.
+ slaveState <= STATE_BUSY;
+ else
+ -- The frame has been aborted.
+ -- Reset the received frame length.
+ inboundFrameLength <= 0;
+ end if;
+ else
+ -- Write frame content into the frame buffer.
+
+ -- Check which frame index that is written.
+ case inboundFrameLength is
+ when 0 =>
+ vc <= slaveData_i(25);
+ crf <= slaveData_i(24);
+ prio <= slaveData_i(23 downto 22);
+ tt <= slaveData_i(21 downto 20);
+ ftype <= slaveData_i(19 downto 16);
+ destinationId <= slaveData_i(15 downto 0);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 1 =>
+ sourceId <= slaveData_i(31 downto 16);
+ transaction <= slaveData_i(15 downto 12);
+ size <= slaveData_i(11 downto 8);
+ srcTid <= slaveData_i(7 downto 0);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 2 =>
+ hopCount <= slaveData_i(31 downto 24);
+ configOffset <= slaveData_i(23 downto 3);
+ wdptr <= slaveData_i(2);
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 3 =>
+ -- Note that crc will be assigned here if there are no
+ -- content in the frame.
+ content(63 downto 32) <= slaveData_i;
+ inboundFrameLength <= inboundFrameLength + 1;
+ when 4 =>
+ content(31 downto 0) <= slaveData_i;
+ inboundFrameLength <= inboundFrameLength + 1;
+ when others =>
+ -- Dont support longer frames.
+ -- REMARK: Add support for longer frames??? Especially
+ -- received frames that only should be routed...
+ end case;
+ end if;
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ else
+ -- Reading request.
+
+ -- Reading the status address.
+ -- Always indicate that we are ready to accept a new frame.
+ slaveData_o <= '0';
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ end if;
+ else
+ -- No cycle is active.
+ end if;
+
+ when STATE_BUSY =>
+ ---------------------------------------------------------------------
+ -- Waiting for a received frame to be processed.
+ ---------------------------------------------------------------------
+
+ -- Check if any cycle is active.
+ if ((slaveCyc_i = '1') and (slaveStb_i = '1') and (slaveAck = '0')) then
+ -- Cycle is active.
+
+ -- Check if writing.
+ if (slaveWe_i = '1') then
+ -- Writing.
+ -- Dont do anything.
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ else
+ -- Read port data address.
+
+ -- Reading the status address.
+ -- Always indicate that we are busy.
+ slaveData_o <= '1';
+
+ -- Send acknowledge.
+ slaveAck <= '1';
+ end if;
+ else
+ -- No cycle is active.
+ -- Dont do anything.
+ end if;
+
+ -- Check if the master process has processed the received frame.
+ if (inboundFrameComplete = '1') then
+ -- The master has processed the frame.
+ inboundFrameReady <= '0';
+ inboundFrameLength <= 0;
+ slaveState <= STATE_READY;
+ else
+ -- The master is not ready yet.
+ -- Dont do anything.
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+ slaveAck_o <= slaveAck;
+
+ -----------------------------------------------------------------------------
+ -- Logic implementing the routing table access.
+ -----------------------------------------------------------------------------
+
+ -- Lookup interface port memory signals.
+ lookupEnable <= '1' when (lookupStb_i = '1') and (lookupAddr_i(15 downto 11) = "00000") else '0';
+ lookupAddress <= lookupAddr_i(10 downto 0);
+ lookupData_o <= lookupData when (lookupEnable = '1') else routeTablePortDefault;
+ lookupAck_o <= lookupAck;
+ LookupProcess: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ lookupAck <= '0';
+ elsif (clk'event and clk = '1') then
+ if (lookupAck = '0') then
+ if (lookupStb_i = '1') then
+ lookupAck <= '1';
+ end if;
+ else
+ lookupAck <= '0';
+ end if;
+ end if;
+ end process;
+
+ -- Dual port memory containing the routing table.
+ RoutingTable: MemoryDualPort
+ generic map(
+ ADDRESS_WIDTH=>11, DATA_WIDTH=>8)
+ port map(
+ clkA_i=>clk, enableA_i=>routeTableEnable, writeEnableA_i=>routeTableWrite,
+ addressA_i=>routeTableAddress,
+ dataA_i=>routeTablePortWrite, dataA_o=>routeTablePortRead,
+ clkB_i=>clk, enableB_i=>lookupEnable,
+ addressB_i=>lookupAddress, dataB_o=>lookupData);
+
+ -----------------------------------------------------------------------------
+ -- Configuration memory.
+ -----------------------------------------------------------------------------
+
+ portLinkTimeout_o <= portLinkTimeout;
+ outputPortEnable_o <= outputPortEnable;
+ inputPortEnable_o <= inputPortEnable;
+
+ configStb_o <= '1' when ((configEnable = '1') and (configAddress(23 downto 16) /= x"00")) else '0';
+ configWe_o <= configWrite;
+ configAddr_o <= configAddress;
+ configData_o <= configDataWrite;
+ configDataRead <= configData_i when (configAddress(23 downto 16) /= x"00") else
+ configDataReadInternal;
+
+ ConfigMemory: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ configDataReadInternal <= (others => '0');
+
+ routeTableEnable <= '1';
+ routeTableWrite <= '0';
+ routeTableAddress <= (others => '0');
+ routeTablePortWrite <= (others => '0');
+ routeTablePortDefault <= (others => '0');
+
+ discovered <= '0';
+
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ componentTag <= (others => '0');
+
+ portLinkTimeout <= (others => '1');
+
+ -- REMARK: These should be set to zero when a port gets initialized...
+ outputPortEnable <= (others => '0');
+ inputPortEnable <= (others => '0');
+
+ localAckIdWrite_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ routeTableWrite <= '0';
+ localAckIdWrite_o <= (others => '0');
+
+ if (configEnable = '1') then
+ -- Check if the access is into implementation defined space or if the
+ -- access should be handled here.
+ if (configAddress(23 downto 16) /= x"00") then
+ -- Accessing implementation defined space.
+ -- Make an external access and return the resonse.
+ configDataReadInternal <= (others=>'0');
+ else
+ -- Access should be handled here.
+
+ case (configAddress) is
+ when x"000000" =>
+ -----------------------------------------------------------------
+ -- Device Identity CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= DEVICE_IDENTITY;
+ configDataReadInternal(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
+
+ when x"000004" =>
+ -----------------------------------------------------------------
+ -- Device Information CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 0) <= DEVICE_REV;
+
+ when x"000008" =>
+ -----------------------------------------------------------------
+ -- Assembly Identity CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= ASSY_IDENTITY;
+ configDataReadInternal(15 downto 0) <= ASSY_VENDOR_IDENTITY;
+
+ when x"00000c" =>
+ -----------------------------------------------------------------
+ -- Assembly Informaiton CAR. Read-only.
+ -----------------------------------------------------------------
+
+ configDataReadInternal(31 downto 16) <= ASSY_REV;
+ configDataReadInternal(15 downto 0) <= x"0100";
+
+ when x"000010" =>
+ -----------------------------------------------------------------
+ -- Processing Element Features CAR. Read-only.
+ -----------------------------------------------------------------
+
+ -- Bridge.
+ configDataReadInternal(31) <= '0';
+
+ -- Memory.
+ configDataReadInternal(30) <= '0';
+
+ -- Processor.
+ configDataReadInternal(29) <= '0';
+
+ -- Switch.
+ configDataReadInternal(28) <= '1';
+
+ -- Reserved.
+ configDataReadInternal(27 downto 10) <= (others => '0');
+
+ -- Extended route table configuration support.
+ configDataReadInternal(9) <= '0';
+
+ -- Standard route table configuration support.
+ configDataReadInternal(8) <= '1';
+
+ -- Reserved.
+ configDataReadInternal(7 downto 5) <= (others => '0');
+
+ -- Common transport large system support.
+ configDataReadInternal(4) <= '1';
+
+ -- Extended features.
+ configDataReadInternal(3) <= '1';
+
+ -- Extended addressing support.
+ -- Not a processing element.
+ configDataReadInternal(2 downto 0) <= "000";
+
+ when x"000014" =>
+ -----------------------------------------------------------------
+ -- Switch Port Information CAR. Read-only.
+ -----------------------------------------------------------------
+
+ -- Reserved.
+ configDataReadInternal(31 downto 16) <= (others => '0');
+
+ -- PortTotal.
+ configDataReadInternal(15 downto 8) <=
+ std_logic_vector(to_unsigned(SWITCH_PORTS, 8));
+
+ -- PortNumber.
+ configDataReadInternal(7 downto 0) <= inboundFramePort;
+
+ when x"000034" =>
+ -----------------------------------------------------------------
+ -- Switch Route Table Destination ID Limit CAR.
+ -----------------------------------------------------------------
+
+ -- Max_destId.
+ -- Support 2048 addresses.
+ configDataReadInternal(15 downto 0) <= x"0800";
+
+ when x"000068" =>
+ -----------------------------------------------------------------
+ -- Host Base Device ID Lock CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Check if this field has been written before.
+ if (hostBaseDeviceIdLocked = '0') then
+ -- The field has not been written.
+ -- Lock the field and set the host base device id.
+ hostBaseDeviceIdLocked <= '1';
+ hostBaseDeviceId <= configDataWrite(15 downto 0);
+ else
+ -- The field has been written.
+ -- Check if the written data is the same as the stored.
+ if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
+ -- Same as stored, reset the value to its initial value.
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ else
+ -- Not writing the same as the stored value.
+ -- Ignore the write.
+ end if;
+ end if;
+ end if;
+
+ configDataReadInternal(31 downto 16) <= (others => '0');
+ configDataReadInternal(15 downto 0) <= hostBaseDeviceId;
+
+ when x"00006c" =>
+ -----------------------------------------------------------------
+ -- Component TAG CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ componentTag <= configDataWrite;
+ end if;
+
+ configDataReadInternal <= componentTag;
+
+ when x"000070" =>
+ -----------------------------------------------------------------
+ -- Standard Route Configuration Destination ID Select CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the address to access the routing table.
+ routeTableAddress <= configDataWrite(10 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 11) <= (others => '0');
+ configDataReadInternal(10 downto 0) <= routeTableAddress;
+
+ when x"000074" =>
+ -----------------------------------------------------------------
+ -- Standard Route Configuration Port Select CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the port information for the address selected by the
+ -- above register.
+ routeTableWrite <= '1';
+ routeTablePortWrite <= configDataWrite(7 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= (others => '0');
+ configDataReadInternal(7 downto 0) <= routeTablePortRead;
+
+ when x"000078" =>
+ -----------------------------------------------------------------
+ -- Standard Route Default Port CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ -- Write the default route device id.
+ routeTablePortDefault <= configDataWrite(7 downto 0);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= (others => '0');
+ configDataReadInternal(7 downto 0) <= routeTablePortDefault;
+
+ when x"000100" =>
+ -----------------------------------------------------------------
+ -- Extended features. LP-Serial Register Block Header.
+ -----------------------------------------------------------------
+
+ -- One feature only, 0x0003=Generic End Point Free Device.
+ configDataReadInternal(31 downto 16) <= x"0000";
+ configDataReadInternal(15 downto 0) <= x"0003";
+
+ when x"000120" =>
+ -----------------------------------------------------------------
+ -- Port Link Timeout Control CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ portLinkTimeout <= configDataWrite(31 downto 8);
+ end if;
+
+ configDataReadInternal(31 downto 8) <= portLinkTimeout;
+ configDataReadInternal(7 downto 0) <= x"00";
+
+ when x"00013c" =>
+ -----------------------------------------------------------------
+ -- Port General Control CSR.
+ -----------------------------------------------------------------
+
+ if (configWrite = '1') then
+ discovered <= configDataWrite(29);
+ end if;
+
+ configDataReadInternal(31 downto 30) <= "00";
+ configDataReadInternal(29) <= discovered;
+ configDataReadInternal(28 downto 0) <= (others => '0');
+
+ when others =>
+ -----------------------------------------------------------------
+ -- Other port specific registers.
+ -----------------------------------------------------------------
+
+ -- Make sure the output is always set to something.
+ configDataReadInternal <= (others=>'0');
+
+ -- Iterate through all active ports.
+ for portIndex in 0 to SWITCH_PORTS-1 loop
+
+ if(unsigned(configAddress) = (x"000148" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Local ackID CSR.
+ -----------------------------------------------------------------
+ if (configWrite = '1') then
+ localAckIdWrite_o(portIndex) <= '1';
+ clrOutstandingAckId_o(portIndex) <= configDataWrite(31);
+ inboundAckId_o(portIndex) <= configDataWrite(28 downto 24);
+ outstandingAckId_o(portIndex) <= configDataWrite(12 downto 8);
+ outboundAckId_o(portIndex) <= configDataWrite(4 downto 0);
+ end if;
+ configDataReadInternal(31 downto 29) <= (others => '0');
+ configDataReadInternal(28 downto 24) <= inboundAckId_i(portIndex);
+ configDataReadInternal(23 downto 13) <= (others => '0');
+ configDataReadInternal(12 downto 8) <= outstandingAckId_i(portIndex);
+ configDataReadInternal(7 downto 5) <= (others => '0');
+ configDataReadInternal(4 downto 0) <= outboundAckId_i(portIndex);
+
+ elsif(unsigned(configAddress) = (x"000154" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Control 2 CSR.
+ -----------------------------------------------------------------
+ configDataReadInternal <= (others => '0');
+
+ elsif(unsigned(configAddress) = (x"000158" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Error and Status CSR.
+ -----------------------------------------------------------------
+ -- Idle Sequence 2 Support.
+ configDataReadInternal(31) <= '0';
+
+ -- Idle Sequence 2 Enable.
+ configDataReadInternal(30) <= '0';
+
+ -- Idle Sequence.
+ configDataReadInternal(29) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(28) <= '0';
+
+ -- Flow Control Mode.
+ configDataReadInternal(27) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(26 downto 21) <= (others => '0');
+
+ -- Output retry-encountered.
+ configDataReadInternal(20) <= '0';
+
+ -- Output retried.
+ configDataReadInternal(19) <= '0';
+
+ -- Output retried-stopped.
+ configDataReadInternal(18) <= '0';
+
+ -- Output error-encountered.
+ configDataReadInternal(17) <= '0';
+
+ -- Output error-stopped.
+ configDataReadInternal(16) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(15 downto 11) <= (others => '0');
+
+ -- Input retry-stopped.
+ configDataReadInternal(10) <= '0';
+
+ -- Input error-encountered.
+ configDataReadInternal(9) <= '0';
+
+ -- Input error-stopped.
+ configDataReadInternal(8) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(7 downto 5) <= (others => '0');
+
+ -- Port-write pending.
+ configDataReadInternal(4) <= '0';
+
+ -- Port unavailable.
+ configDataReadInternal(3) <= '0';
+
+ -- Port error.
+ configDataReadInternal(2) <= '0';
+
+ -- Port OK.
+ configDataReadInternal(1) <= linkInitialized_i(portIndex);
+
+ -- Port uninitialized.
+ configDataReadInternal(0) <= not linkInitialized_i(portIndex);
+
+ elsif(unsigned(configAddress) = (x"00015c" + (x"000020"*portIndex))) then
+ -----------------------------------------------------------------
+ -- Port N Control CSR.
+ -----------------------------------------------------------------
+
+ -- Port Width Support.
+ configDataReadInternal(31 downto 30) <= (others=>'0');
+
+ -- Initialized Port Width.
+ configDataReadInternal(29 downto 27) <= (others=>'0');
+
+ -- Port Width Override.
+ configDataReadInternal(26 downto 24) <= (others=>'0');
+
+ -- Port disable.
+ configDataReadInternal(23) <= '0';
+
+ -- Output Port Enable.
+ if (configWrite = '1') then
+ outputPortEnable(portIndex) <= configDataWrite(22);
+ end if;
+ configDataReadInternal(22) <= outputPortEnable(portIndex);
+
+ -- Input Port Enable.
+ if (configWrite = '1') then
+ inputPortEnable(portIndex) <= configDataWrite(21);
+ end if;
+ configDataReadInternal(21) <= inputPortEnable(portIndex);
+
+ -- Error Checking Disabled.
+ configDataReadInternal(20) <= '0';
+
+ -- Multicast-event Participant.
+ configDataReadInternal(19) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(18) <= '0';
+
+ -- Enumeration Boundry.
+ configDataReadInternal(17) <= '0';
+
+ -- Reserved.
+ configDataReadInternal(16) <= '0';
+
+ -- Extended Port Width Override.
+ configDataReadInternal(15 downto 14) <= (others=>'0');
+
+ -- Extended Port Width Support.
+ configDataReadInternal(13 downto 12) <= (others=>'0');
+
+ -- Implementation defined.
+ configDataReadInternal(11 downto 4) <= (others=>'0');
+
+ -- Reserved.
+ configDataReadInternal(3 downto 1) <= (others=>'0');
+
+ -- Port Type.
+ configDataReadInternal(0) <= '1';
+ end if;
+ end loop;
+
+ end case;
+ end if;
+ else
+ -- Config memory not enabled.
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity RouteTableInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ stb_i : in Array1(WIDTH-1 downto 0);
+ addr_i : in Array16(WIDTH-1 downto 0);
+ dataM_o : out Array8(WIDTH-1 downto 0);
+ ack_o : out Array1(WIDTH-1 downto 0);
+
+ stb_o : out std_logic;
+ addr_o : out std_logic_vector(15 downto 0);
+ dataS_i : in std_logic_vector(7 downto 0);
+ ack_i : in std_logic);
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture RouteTableInterconnectImpl of RouteTableInterconnect is
+ signal activeCycle : std_logic;
+ signal selectedMaster : natural range 0 to WIDTH-1;
+begin
+
+ -----------------------------------------------------------------------------
+ -- Arbitration.
+ -----------------------------------------------------------------------------
+ Arbiter: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ activeCycle <= '0';
+ selectedMaster <= 0;
+ elsif (clk'event and clk = '1') then
+ if (activeCycle = '0') then
+ for i in 0 to WIDTH-1 loop
+ if (stb_i(i) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= i;
+ end if;
+ end loop;
+ else
+ if (stb_i(selectedMaster) = '0') then
+ activeCycle <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Interconnection.
+ -----------------------------------------------------------------------------
+ stb_o <= stb_i(selectedMaster) and activeCycle;
+ addr_o <= addr_i(selectedMaster);
+
+ Interconnect: for i in 0 to WIDTH-1 generate
+ dataM_o(i) <= dataS_i;
+ ack_o(i) <= ack_i when (selectedMaster = i) else '0';
+ end generate;
+
+end architecture;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity SwitchPortInterconnect is
+ generic(
+ WIDTH : natural range 1 to 256 := 8);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ masterCyc_i : in Array1(WIDTH-1 downto 0);
+ masterStb_i : in Array1(WIDTH-1 downto 0);
+ masterWe_i : in Array1(WIDTH-1 downto 0);
+ masterAddr_i : in Array10(WIDTH-1 downto 0);
+ masterData_i : in Array32(WIDTH-1 downto 0);
+ masterData_o : out Array1(WIDTH-1 downto 0);
+ masterAck_o : out Array1(WIDTH-1 downto 0);
+
+ slaveCyc_o : out Array1(WIDTH-1 downto 0);
+ slaveStb_o : out Array1(WIDTH-1 downto 0);
+ slaveWe_o : out Array1(WIDTH-1 downto 0);
+ slaveAddr_o : out Array10(WIDTH-1 downto 0);
+ slaveData_o : out Array32(WIDTH-1 downto 0);
+ slaveData_i : in Array1(WIDTH-1 downto 0);
+ slaveAck_i : in Array1(WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture SwitchPortInterconnectImpl of SwitchPortInterconnect is
+ signal activeCycle : std_logic;
+ signal selectedMaster : natural range 0 to WIDTH-1;
+ signal selectedSlave : natural range 0 to WIDTH-1;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Arbitration process.
+ -----------------------------------------------------------------------------
+
+ RoundRobinArbiter: process(areset_n, clk)
+ variable index : natural range 0 to WIDTH-1 := 0;
+ begin
+ if (areset_n = '0') then
+ activeCycle <= '0';
+ selectedMaster <= 0;
+ elsif (clk'event and clk = '1') then
+ -- Check if a cycle is ongoing.
+ if (activeCycle = '0') then
+ -- No ongoing cycles.
+
+ -- Iterate through all ports and check if any new cycle has started.
+ for i in 0 to WIDTH-1 loop
+ if ((selectedMaster+i) >= WIDTH) then
+ index := (selectedMaster+i) - WIDTH;
+ else
+ index := (selectedMaster+i);
+ end if;
+
+ if (masterCyc_i(index) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= index;
+ end if;
+ end loop;
+ else
+ -- Ongoing cycle.
+
+ -- Check if the cycle has ended.
+ if (masterCyc_i(selectedMaster) = '0') then
+ -- Cycle has ended.
+ activeCycle <= '0';
+
+ -- Check if a new cycle has started from another master.
+ -- Start to check from the one that ended its cycle, this way, the
+ -- ports will be scheduled like round-robin.
+ for i in 0 to WIDTH-1 loop
+ if ((selectedMaster+i) >= WIDTH) then
+ index := (selectedMaster+i) - WIDTH;
+ else
+ index := (selectedMaster+i);
+ end if;
+
+ if (masterCyc_i(index) = '1') then
+ activeCycle <= '1';
+ selectedMaster <= index;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Address decoding.
+ -----------------------------------------------------------------------------
+
+ -- Select the last port when the top bit is set.
+ -- The last port must be the maintenance slave port.
+ selectedSlave <= WIDTH-1 when masterAddr_i(selectedMaster)(9) = '1' else
+ to_integer(unsigned(masterAddr_i(selectedMaster)(8 downto 1)));
+
+ -----------------------------------------------------------------------------
+ -- Interconnection matrix.
+ -----------------------------------------------------------------------------
+ Interconnect: for i in 0 to WIDTH-1 generate
+ slaveCyc_o(i) <= masterCyc_i(selectedMaster) when ((activeCycle = '1') and (selectedSlave = i)) else '0';
+ slaveStb_o(i) <= masterStb_i(selectedMaster) when ((activeCycle = '1') and (selectedSlave = i)) else '0';
+ slaveWe_o(i) <= masterWe_i(selectedMaster);
+ slaveAddr_o(i) <= masterAddr_i(selectedMaster);
+ slaveData_o(i) <= masterData_i(selectedMaster);
+ masterData_o(i) <= slaveData_i(selectedSlave);
+ masterAck_o(i) <= slaveAck_i(selectedSlave) when (selectedMaster = i) else '0';
+ end generate;
+
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioSwitch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/RioCommon.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioCommon.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioCommon.vhd (revision 50)
@@ -0,0 +1,1138 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Contains commonly used types, functions, procedures and entities used in
+-- the RapidIO IP library project.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioCommon library.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+use std.textio.all;
+
+
+-------------------------------------------------------------------------------
+-- RioCommon package description.
+-------------------------------------------------------------------------------
+package rio_common is
+ -----------------------------------------------------------------------------
+ -- Commonly used types.
+ -----------------------------------------------------------------------------
+ type Array1 is array (natural range <>) of
+ std_logic;
+ type Array2 is array (natural range <>) of
+ std_logic_vector(1 downto 0);
+ type Array3 is array (natural range <>) of
+ std_logic_vector(2 downto 0);
+ type Array4 is array (natural range <>) of
+ std_logic_vector(3 downto 0);
+ type Array5 is array (natural range <>) of
+ std_logic_vector(4 downto 0);
+ type Array8 is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type Array9 is array (natural range <>) of
+ std_logic_vector(8 downto 0);
+ type Array10 is array (natural range <>) of
+ std_logic_vector(9 downto 0);
+ type Array16 is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type Array32 is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type Array34 is array (natural range <>) of
+ std_logic_vector(33 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Commonly used constants.
+ -----------------------------------------------------------------------------
+
+ -- Symbol types between the serial and the PCS layer.
+ constant SYMBOL_IDLE : std_logic_vector(1 downto 0) := "00";
+ constant SYMBOL_CONTROL : std_logic_vector(1 downto 0) := "01";
+ constant SYMBOL_ERROR : std_logic_vector(1 downto 0) := "10";
+ constant SYMBOL_DATA : std_logic_vector(1 downto 0) := "11";
+
+ -- STYPE0 constants.
+ constant STYPE0_PACKET_ACCEPTED : std_logic_vector(2 downto 0) := "000";
+ constant STYPE0_PACKET_RETRY : std_logic_vector(2 downto 0) := "001";
+ constant STYPE0_PACKET_NOT_ACCEPTED : std_logic_vector(2 downto 0) := "010";
+ constant STYPE0_RESERVED : std_logic_vector(2 downto 0) := "011";
+ constant STYPE0_STATUS : std_logic_vector(2 downto 0) := "100";
+ constant STYPE0_VC_STATUS : std_logic_vector(2 downto 0) := "101";
+ constant STYPE0_LINK_RESPONSE : std_logic_vector(2 downto 0) := "110";
+ constant STYPE0_IMPLEMENTATION_DEFINED : std_logic_vector(2 downto 0) := "111";
+
+ -- STYPE1 constants.
+ constant STYPE1_START_OF_PACKET : std_logic_vector(2 downto 0) := "000";
+ constant STYPE1_STOMP : std_logic_vector(2 downto 0) := "001";
+ constant STYPE1_END_OF_PACKET : std_logic_vector(2 downto 0) := "010";
+ constant STYPE1_RESTART_FROM_RETRY : std_logic_vector(2 downto 0) := "011";
+ constant STYPE1_LINK_REQUEST : std_logic_vector(2 downto 0) := "100";
+ constant STYPE1_MULTICAST_EVENT : std_logic_vector(2 downto 0) := "101";
+ constant STYPE1_RESERVED : std_logic_vector(2 downto 0) := "110";
+ constant STYPE1_NOP : std_logic_vector(2 downto 0) := "111";
+
+ -- FTYPE constants.
+ constant FTYPE_REQUEST_CLASS : std_logic_vector(3 downto 0) := "0010";
+ constant FTYPE_WRITE_CLASS : std_logic_vector(3 downto 0) := "0101";
+ constant FTYPE_STREAMING_WRITE_CLASS : std_logic_vector(3 downto 0) := "0110";
+ constant FTYPE_MAINTENANCE_CLASS : std_logic_vector(3 downto 0) := "1000";
+ constant FTYPE_RESPONSE_CLASS : std_logic_vector(3 downto 0) := "1101";
+ constant FTYPE_DOORBELL_CLASS : std_logic_vector(3 downto 0) := "1010";
+ constant FTYPE_MESSAGE_CLASS : std_logic_vector(3 downto 0) := "0010";
+
+ -- TTYPE Constants
+ constant TTYPE_MAINTENANCE_READ_REQUEST : std_logic_vector(3 downto 0) := "0000";
+ constant TTYPE_MAINTENANCE_WRITE_REQUEST : std_logic_vector(3 downto 0) := "0001";
+ constant TTYPE_MAINTENANCE_READ_RESPONSE : std_logic_vector(3 downto 0) := "0010";
+ constant TTYPE_MAINTENANCE_WRITE_RESPONSE : std_logic_vector(3 downto 0) := "0011";
+ constant TTYPE_NREAD_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+ constant TTYPE_NWRITE_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
+
+ constant LINK_REQUEST_CMD_RESET_DEVICE : std_logic_vector(2 downto 0) := "011";
+ constant LINK_REQUEST_CMD_INPUT_STATUS : std_logic_vector(2 downto 0) := "100";
+
+ constant PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID : std_logic_vector(4 downto 0) := "00001";
+ constant PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC : std_logic_vector(4 downto 0) := "00010";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED : std_logic_vector(4 downto 0) := "00011";
+ constant PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC : std_logic_vector(4 downto 0) := "00100";
+ constant PACKET_NOT_ACCEPTED_CAUSE_INVALID_CHARACTER : std_logic_vector(4 downto 0) := "00101";
+ constant PACKET_NOT_ACCEPTED_CAUSE_NO_RESOURCES : std_logic_vector(4 downto 0) := "00110";
+ constant PACKET_NOT_ACCEPTED_CAUSE_LOSS_DESCRAMBLER : std_logic_vector(4 downto 0) := "00111";
+ constant PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR : std_logic_vector(4 downto 0) := "11111";
+
+ -----------------------------------------------------------------------------
+ -- Types used in simulations.
+ -----------------------------------------------------------------------------
+ type ByteArray is array (natural range <>) of
+ std_logic_vector(7 downto 0);
+ type HalfwordArray is array (natural range <>) of
+ std_logic_vector(15 downto 0);
+ type WordArray is array (natural range <>) of
+ std_logic_vector(31 downto 0);
+ type DoublewordArray is array (natural range <>) of
+ std_logic_vector(63 downto 0);
+
+ -- Type defining a RapidIO frame.
+ type RioFrame is record
+ length : natural range 0 to 69;
+ payload : WordArray(0 to 68);
+ end record;
+ type RioFrameArray is array (natural range <>) of RioFrame;
+
+ -- Type defining a RapidIO payload.
+ type RioPayload is record
+ length : natural range 0 to 133;
+ data : HalfwordArray(0 to 132);
+ end record;
+
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive);
+
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload)
+ return RioFrame;
+
+ ---------------------------------------------------------------------------
+ -- Create a NWRITE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a NREAD RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to report file and output
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print to spec file
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string );
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd;
+
+end package;
+
+-------------------------------------------------------------------------------
+-- RioCommon package body description.
+-------------------------------------------------------------------------------
+package body rio_common is
+ -----------------------------------------------------------------------------
+ -- Crc5 calculation function.
+ -- ITU, polynom=0x15.
+ -----------------------------------------------------------------------------
+ function Crc5(constant data : in std_logic_vector(18 downto 0);
+ constant crc : in std_logic_vector(4 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 31) of std_logic_vector(7 downto 0);
+ constant crcTable : crcTableType := (
+ x"00", x"15", x"1f", x"0a", x"0b", x"1e", x"14", x"01",
+ x"16", x"03", x"09", x"1c", x"1d", x"08", x"02", x"17",
+ x"19", x"0c", x"06", x"13", x"12", x"07", x"0d", x"18",
+ x"0f", x"1a", x"10", x"05", x"04", x"11", x"1b", x"0e" );
+ variable index : natural range 0 to 31;
+ variable result : std_logic_vector(4 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(18 downto 14) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(13 downto 9) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned(data(8 downto 4) xor result));
+ result := crcTable(index)(4 downto 0);
+ index := to_integer(unsigned((data(3 downto 0) & '0') xor result));
+ return crcTable(index)(4 downto 0);
+ end Crc5;
+
+ ---------------------------------------------------------------------------
+ -- Create a RapidIO physical layer control symbol.
+ ---------------------------------------------------------------------------
+ function RioControlSymbolCreate(
+ constant stype0 : in std_logic_vector(2 downto 0);
+ constant parameter0 : in std_logic_vector(4 downto 0);
+ constant parameter1 : in std_logic_vector(4 downto 0);
+ constant stype1 : in std_logic_vector(2 downto 0);
+ constant cmd : in std_logic_vector(2 downto 0))
+ return std_logic_vector is
+ variable returnValue : std_logic_vector(31 downto 0);
+ variable symbolData : std_logic_vector(18 downto 0);
+ begin
+ symbolData(18 downto 16) := stype0;
+ symbolData(15 downto 11) := parameter0;
+ symbolData(10 downto 6) := parameter1;
+ symbolData(5 downto 3) := stype1;
+ symbolData(2 downto 0) := cmd;
+
+ returnValue(31 downto 13) := symbolData;
+ returnValue(12 downto 8) := Crc5(symbolData, "11111");
+ returnValue(7 downto 0) := x"00";
+
+ return returnValue;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Crc16 calculation function.
+ -- CITT, polynom=0x1021.
+ -----------------------------------------------------------------------------
+ function Crc16(constant data : in std_logic_vector(15 downto 0);
+ constant crc : in std_logic_vector(15 downto 0))
+ return std_logic_vector is
+ type crcTableType is array (0 to 255) of std_logic_vector(15 downto 0);
+ constant crcTable : crcTableType := (
+ x"0000", x"1021", x"2042", x"3063", x"4084", x"50a5", x"60c6", x"70e7",
+ x"8108", x"9129", x"a14a", x"b16b", x"c18c", x"d1ad", x"e1ce", x"f1ef",
+ x"1231", x"0210", x"3273", x"2252", x"52b5", x"4294", x"72f7", x"62d6",
+ x"9339", x"8318", x"b37b", x"a35a", x"d3bd", x"c39c", x"f3ff", x"e3de",
+ x"2462", x"3443", x"0420", x"1401", x"64e6", x"74c7", x"44a4", x"5485",
+ x"a56a", x"b54b", x"8528", x"9509", x"e5ee", x"f5cf", x"c5ac", x"d58d",
+ x"3653", x"2672", x"1611", x"0630", x"76d7", x"66f6", x"5695", x"46b4",
+ x"b75b", x"a77a", x"9719", x"8738", x"f7df", x"e7fe", x"d79d", x"c7bc",
+ x"48c4", x"58e5", x"6886", x"78a7", x"0840", x"1861", x"2802", x"3823",
+ x"c9cc", x"d9ed", x"e98e", x"f9af", x"8948", x"9969", x"a90a", x"b92b",
+ x"5af5", x"4ad4", x"7ab7", x"6a96", x"1a71", x"0a50", x"3a33", x"2a12",
+ x"dbfd", x"cbdc", x"fbbf", x"eb9e", x"9b79", x"8b58", x"bb3b", x"ab1a",
+ x"6ca6", x"7c87", x"4ce4", x"5cc5", x"2c22", x"3c03", x"0c60", x"1c41",
+ x"edae", x"fd8f", x"cdec", x"ddcd", x"ad2a", x"bd0b", x"8d68", x"9d49",
+ x"7e97", x"6eb6", x"5ed5", x"4ef4", x"3e13", x"2e32", x"1e51", x"0e70",
+ x"ff9f", x"efbe", x"dfdd", x"cffc", x"bf1b", x"af3a", x"9f59", x"8f78",
+ x"9188", x"81a9", x"b1ca", x"a1eb", x"d10c", x"c12d", x"f14e", x"e16f",
+ x"1080", x"00a1", x"30c2", x"20e3", x"5004", x"4025", x"7046", x"6067",
+ x"83b9", x"9398", x"a3fb", x"b3da", x"c33d", x"d31c", x"e37f", x"f35e",
+ x"02b1", x"1290", x"22f3", x"32d2", x"4235", x"5214", x"6277", x"7256",
+ x"b5ea", x"a5cb", x"95a8", x"8589", x"f56e", x"e54f", x"d52c", x"c50d",
+ x"34e2", x"24c3", x"14a0", x"0481", x"7466", x"6447", x"5424", x"4405",
+ x"a7db", x"b7fa", x"8799", x"97b8", x"e75f", x"f77e", x"c71d", x"d73c",
+ x"26d3", x"36f2", x"0691", x"16b0", x"6657", x"7676", x"4615", x"5634",
+ x"d94c", x"c96d", x"f90e", x"e92f", x"99c8", x"89e9", x"b98a", x"a9ab",
+ x"5844", x"4865", x"7806", x"6827", x"18c0", x"08e1", x"3882", x"28a3",
+ x"cb7d", x"db5c", x"eb3f", x"fb1e", x"8bf9", x"9bd8", x"abbb", x"bb9a",
+ x"4a75", x"5a54", x"6a37", x"7a16", x"0af1", x"1ad0", x"2ab3", x"3a92",
+ x"fd2e", x"ed0f", x"dd6c", x"cd4d", x"bdaa", x"ad8b", x"9de8", x"8dc9",
+ x"7c26", x"6c07", x"5c64", x"4c45", x"3ca2", x"2c83", x"1ce0", x"0cc1",
+ x"ef1f", x"ff3e", x"cf5d", x"df7c", x"af9b", x"bfba", x"8fd9", x"9ff8",
+ x"6e17", x"7e36", x"4e55", x"5e74", x"2e93", x"3eb2", x"0ed1", x"1ef0" );
+ variable index : natural range 0 to 255;
+ variable result : std_logic_vector(15 downto 0);
+ begin
+ result := crc;
+ index := to_integer(unsigned(data(15 downto 8) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ index := to_integer(unsigned(data(7 downto 0) xor result(15 downto 8)));
+ result := crcTable(index) xor (result(7 downto 0) & x"00");
+ return result;
+ end Crc16;
+
+ ---------------------------------------------------------------------------
+ -- Create a randomly initialized data array.
+ ---------------------------------------------------------------------------
+ procedure CreateRandomPayload(
+ variable payload : out HalfwordArray(0 to 132);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+
+ procedure CreateRandomPayload(
+ variable payload : out DoublewordArray(0 to 31);
+ variable seed1 : inout positive;
+ variable seed2 : inout positive) is
+ variable rand: real;
+ variable int_rand: integer;
+ variable stim: std_logic_vector(7 downto 0);
+ begin
+ for i in payload'range loop
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(23 downto 16) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(31 downto 24) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(39 downto 32) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(47 downto 40) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(55 downto 48) := std_logic_vector(to_unsigned(int_rand, 8));
+ uniform(seed1, seed2, rand);
+ int_rand := integer(trunc(rand*256.0));
+ payload(i)(63 downto 56) := std_logic_vector(to_unsigned(int_rand, 8));
+ end loop;
+ end procedure;
+ ---------------------------------------------------------------------------
+ -- Create a generic RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioFrameCreate(
+ constant ackId : in std_logic_vector(4 downto 0);
+ constant vc : in std_logic;
+ constant crf : in std_logic;
+ constant prio : in std_logic_vector(1 downto 0);
+ constant tt : in std_logic_vector(1 downto 0);
+ constant ftype : in std_logic_vector(3 downto 0);
+ constant sourceId : in std_logic_vector(15 downto 0);
+ constant destId : in std_logic_vector(15 downto 0);
+ constant payload : in RioPayload) return RioFrame is
+ variable frame : RioFrame;
+ variable result : HalfwordArray(0 to 137);
+ variable crc : std_logic_vector(15 downto 0) := x"ffff";
+ begin
+ -- Add the header and addresses.
+ result(0) := ackId & "0" & vc & crf & prio & tt & ftype;
+ result(1) := destId;
+ result(2) := sourceId;
+
+ -- Update the calculated CRC with the header contents.
+ crc := Crc16("00000" & result(0)(10 downto 0), crc);
+ crc := Crc16(result(1), crc);
+ crc := Crc16(result(2), crc);
+
+ -- Check if a single CRC should be added or two.
+ if (payload.length <= 37) then
+ -- Single CRC.
+ for i in 0 to payload.length-1 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+3) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 1) then
+ result(payload.length+4) := x"0000";
+ frame.length := (payload.length+5) / 2;
+ else
+ frame.length := (payload.length+4) / 2;
+ end if;
+ else
+ -- Double CRC.
+ for i in 0 to 36 loop
+ result(i+3) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+
+ -- Add in-the-middle crc.
+ result(40) := crc;
+ crc := Crc16(crc, crc);
+
+ for i in 37 to payload.length-1 loop
+ result(i+4) := payload.data(i);
+ crc := Crc16(payload.data(i), crc);
+ end loop;
+ result(payload.length+4) := crc;
+
+ -- Check if paddning is needed to make the payload even 32-bit.
+ if ((payload.length mod 2) = 0) then
+ result(payload.length+5) := x"0000";
+ frame.length := (payload.length+6) / 2;
+ else
+ frame.length := (payload.length+5) / 2;
+ end if;
+ end if;
+
+ -- Update the result length.
+ for i in 0 to frame.length-1 loop
+ frame.payload(i) := result(2*i) & result(2*i+1);
+ end loop;
+
+ return frame;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNwrite(
+ constant wrsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0);
+ constant dataLength : in natural range 1 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := wrsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ --
+ -----------------------------------------------------------------------------
+ function RioNread(
+ constant rdsize : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant address : in std_logic_vector(28 downto 0);
+ constant wdptr : in std_logic;
+ constant xamsbs : in std_logic_vector(1 downto 0))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := "0100";
+ payload.data(0)(11 downto 8) := rdsize;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1) := address(28 downto 13);
+
+ payload.data(2)(15 downto 3) := address(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := xamsbs;
+
+ payload.length := 3;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a RESPONSE RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioResponse(
+ constant status : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant dataLength : in natural range 0 to 32;
+ constant data : in DoublewordArray(0 to 31))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(11 downto 8) := status;
+ payload.data(0)(7 downto 0) := tid;
+
+ if (dataLength = 0) then
+ payload.data(0)(15 downto 12) := "0000";
+ payload.length := 1;
+ else
+ payload.data(0)(15 downto 12) := "1000";
+
+ for i in 0 to dataLength-1 loop
+ payload.data(1+4*i) := data(i)(63 downto 48);
+ payload.data(2+4*i) := data(i)(47 downto 32);
+ payload.data(3+4*i) := data(i)(31 downto 16);
+ payload.data(4+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 1 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Create a Maintenance RapidIO frame.
+ ---------------------------------------------------------------------------
+ function RioMaintenance(
+ constant transaction : in std_logic_vector(3 downto 0);
+ constant size : in std_logic_vector(3 downto 0);
+ constant tid : in std_logic_vector(7 downto 0);
+ constant hopCount : in std_logic_vector(7 downto 0);
+ constant configOffset : in std_logic_vector(20 downto 0);
+ constant wdptr : in std_logic;
+ constant dataLength : in natural range 0 to 8;
+ constant data : in DoublewordArray(0 to 7))
+ return RioPayload is
+ variable payload : RioPayload;
+ begin
+ payload.data(0)(15 downto 12) := transaction;
+ payload.data(0)(11 downto 8) := size;
+ payload.data(0)(7 downto 0) := tid;
+
+ payload.data(1)(15 downto 8) := hopCount;
+ payload.data(1)(7 downto 0) := configOffset(20 downto 13);
+
+ payload.data(2)(15 downto 3) := configOffset(12 downto 0);
+ payload.data(2)(2) := wdptr;
+ payload.data(2)(1 downto 0) := "00";
+
+ if (dataLength = 0) then
+ payload.length := 3;
+ else
+ for i in 0 to dataLength-1 loop
+ payload.data(3+4*i) := data(i)(63 downto 48);
+ payload.data(4+4*i) := data(i)(47 downto 32);
+ payload.data(5+4*i) := data(i)(31 downto 16);
+ payload.data(6+4*i) := data(i)(15 downto 0);
+ end loop;
+
+ payload.length := 3 + 4*dataLength;
+ end if;
+
+ return payload;
+ end function;
+
+ -----------------------------------------------------------------------------
+ -- Function to convert a std_logic_vector to a string.
+ -----------------------------------------------------------------------------
+ function byteToString(constant byte : std_logic_vector(7 downto 0))
+ return string is
+ constant table : string(1 to 16) := "0123456789abcdef";
+ variable returnValue : string(1 to 2);
+ begin
+ returnValue(1) := table(to_integer(unsigned(byte(7 downto 4))) + 1);
+ returnValue(2) := table(to_integer(unsigned(byte(3 downto 0))) + 1);
+ return returnValue;
+ end function;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test report
+ ---------------------------------------------------------------------------
+ procedure PrintR( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write report note to wave/transcript window
+ report str severity NOTE;
+ end PrintR;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to print test spec
+ ---------------------------------------------------------------------------
+ procedure PrintS( constant str : string ) is
+ file specFile : text;
+ variable specLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to spec file
+ file_open(fStatus, specFile, "testspec.txt", append_mode);
+ write(specLine, string'(str));
+ writeline (specFile, specLine);
+ file_close(specFile);
+ end PrintS;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Assert Expression
+ ---------------------------------------------------------------------------
+ procedure AssertE( constant exp: boolean; constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ if (not exp) then
+ --Write to STD_OUTPUT
+ report(str) severity error;
+ else
+ PrintR("Status: Passed");
+ PrintS("Status: Passed");
+ end if;
+ end AssertE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to Print Error
+ ---------------------------------------------------------------------------
+ procedure PrintE( constant str : string ) is
+ file reportFile : text;
+ variable reportLine, outputLine : line;
+ variable fStatus: FILE_OPEN_STATUS;
+ begin
+ --Write to STD_OUTPUT
+ report str severity error;
+ end PrintE;
+
+ ---------------------------------------------------------------------------
+ -- Procedure to end a test.
+ ---------------------------------------------------------------------------
+ procedure TestEnd is
+ begin
+ assert false report "Test complete." severity failure;
+ wait;
+ end TestEnd;
+
+end rio_common;
+
+
+
+-------------------------------------------------------------------------------
+-- Crc16CITT
+-- A CRC-16 calculator following the implementation proposed in the 2.2
+-- standard.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for Crc16CITT.
+-------------------------------------------------------------------------------
+entity Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for Crc16CITT.
+-------------------------------------------------------------------------------
+architecture Crc16Impl of Crc16CITT is
+ signal d : std_logic_vector(0 to 15);
+ signal c : std_logic_vector(0 to 15);
+ signal e : std_logic_vector(0 to 15);
+ signal cc : std_logic_vector(0 to 15);
+begin
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ d(15) <= d_i(0); d(14) <= d_i(1); d(13) <= d_i(2); d(12) <= d_i(3);
+ d(11) <= d_i(4); d(10) <= d_i(5); d(9) <= d_i(6); d(8) <= d_i(7);
+ d(7) <= d_i(8); d(6) <= d_i(9); d(5) <= d_i(10); d(4) <= d_i(11);
+ d(3) <= d_i(12); d(2) <= d_i(13); d(1) <= d_i(14); d(0) <= d_i(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ c(15) <= crc_i(0); c(14) <= crc_i(1); c(13) <= crc_i(2); c(12) <= crc_i(3);
+ c(11) <= crc_i(4); c(10) <= crc_i(5); c(9) <= crc_i(6); c(8) <= crc_i(7);
+ c(7) <= crc_i(8); c(6) <= crc_i(9); c(5) <= crc_i(10); c(4) <= crc_i(11);
+ c(3) <= crc_i(12); c(2) <= crc_i(13); c(1) <= crc_i(14); c(0) <= crc_i(15);
+
+ -- Calculate the resulting crc.
+ e <= c xor d;
+ cc(0) <= e(4) xor e(5) xor e(8) xor e(12);
+ cc(1) <= e(5) xor e(6) xor e(9) xor e(13);
+ cc(2) <= e(6) xor e(7) xor e(10) xor e(14);
+ cc(3) <= e(0) xor e(7) xor e(8) xor e(11) xor e(15);
+ cc(4) <= e(0) xor e(1) xor e(4) xor e(5) xor e(9);
+ cc(5) <= e(1) xor e(2) xor e(5) xor e(6) xor e(10);
+ cc(6) <= e(0) xor e(2) xor e(3) xor e(6) xor e(7) xor e(11);
+ cc(7) <= e(0) xor e(1) xor e(3) xor e(4) xor e(7) xor e(8) xor e(12);
+ cc(8) <= e(0) xor e(1) xor e(2) xor e(4) xor e(5) xor e(8) xor e(9) xor e(13);
+ cc(9) <= e(1) xor e(2) xor e(3) xor e(5) xor e(6) xor e(9) xor e(10) xor e(14);
+ cc(10) <= e(2) xor e(3) xor e(4) xor e(6) xor e(7) xor e(10) xor e(11) xor e(15);
+ cc(11) <= e(0) xor e(3) xor e(7) xor e(11);
+ cc(12) <= e(0) xor e(1) xor e(4) xor e(8) xor e(12);
+ cc(13) <= e(1) xor e(2) xor e(5) xor e(9) xor e(13);
+ cc(14) <= e(2) xor e(3) xor e(6) xor e(10) xor e(14);
+ cc(15) <= e(3) xor e(4) xor e(7) xor e(11) xor e(15);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ crc_o(15) <= cc(0); crc_o(14) <= cc(1); crc_o(13) <= cc(2); crc_o(12) <= cc(3);
+ crc_o(11) <= cc(4); crc_o(10) <= cc(5); crc_o(9) <= cc(6); crc_o(8) <= cc(7);
+ crc_o(7) <= cc(8); crc_o(6) <= cc(9); crc_o(5) <= cc(10); crc_o(4) <= cc(11);
+ crc_o(3) <= cc(12); crc_o(2) <= cc(13); crc_o(1) <= cc(14); crc_o(0) <= cc(15);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemoryDualPort
+-- Generic synchronous memory with one read/write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemoryDualPort.
+-------------------------------------------------------------------------------
+entity MemoryDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ writeEnableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ dataA_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemoryDualPort.
+-------------------------------------------------------------------------------
+architecture MemoryDualPortImpl of MemoryDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ if (writeEnableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+
+ dataA_o <= memory(to_integer(unsigned(addressA_i)));
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPort
+-- Generic synchronous memory with one write port and one read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPort.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortImpl of MemorySimpleDualPort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ process(clkB_i)
+ begin
+ if (clkB_i'event and clkB_i = '1') then
+ if (enableB_i = '1') then
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySinglePort
+-- Generic synchronous memory with one read/write port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySinglePort.
+-------------------------------------------------------------------------------
+entity MemorySinglePort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clk_i : in std_logic;
+ enable_i : in std_logic;
+ writeEnable_i : in std_logic;
+ address_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySinglePort.
+-------------------------------------------------------------------------------
+architecture MemorySinglePortImpl of MemorySinglePort is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1);
+
+begin
+ process(clk_i)
+ begin
+ if (clk_i'event and clk_i = '1') then
+ if (enable_i = '1') then
+ if (writeEnable_i = '1') then
+ memory(to_integer(unsigned(address_i))) <= data_i;
+ end if;
+
+ data_o <= memory(to_integer(unsigned(address_i)));
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+
+-------------------------------------------------------------------------------
+-- MemorySimpleDualPortAsync
+-- Generic memory with one synchronous write port and one asynchronous read port.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+entity MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1;
+ INIT_VALUE : std_logic := 'U');
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for MemorySimpleDualPortAsync.
+-------------------------------------------------------------------------------
+architecture MemorySimpleDualPortAsyncImpl of MemorySimpleDualPortAsync is
+ type MemoryType is array (natural range <>) of
+ std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ signal memory : MemoryType(0 to (2**ADDRESS_WIDTH)-1) := (others=>(others=>INIT_VALUE));
+
+begin
+ process(clkA_i)
+ begin
+ if (clkA_i'event and clkA_i = '1') then
+ if (enableA_i = '1') then
+ memory(to_integer(unsigned(addressA_i))) <= dataA_i;
+ end if;
+ end if;
+ end process;
+
+ dataB_o <= memory(to_integer(unsigned(addressB_i)));
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- RioFifo1
+-- Simple fifo which is one entry deep.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioFifo1.
+-------------------------------------------------------------------------------
+entity RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioFifo1.
+-------------------------------------------------------------------------------
+architecture RioFifo1Impl of RioFifo1 is
+ signal empty : std_logic;
+ signal full : std_logic;
+begin
+
+ empty_o <= empty;
+ full_o <= full;
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ empty <= '1';
+ full <= '0';
+ data_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (empty = '1') then
+ if (write_i = '1') then
+ empty <= '0';
+ full <= '1';
+ data_o <= data_i;
+ end if;
+ else
+ if (read_i = '1') then
+ empty <= '1';
+ full <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioCommon.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/RioSerial.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioSerial.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioSerial.vhd (revision 50)
@@ -0,0 +1,2428 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing the transmission channel independent parts of the LP-Serial
+-- Physical Layer Specification (RapidIO 2.2, part 6).
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioSerial
+--
+-- clk - System clock.
+-- areset_n - System reset. Asynchronous, active low.
+--
+-- portLinkTimeout_i - The number of ticks to wait for a packet-accepted before
+-- a timeout occurrs.
+-- linkInitialized_o - Indicates if a link partner is answering with valid
+-- status-control-symbols.
+-- inputPortEnable_i - Activate the input port for non-maintenance packets. If
+-- deasserted, only non-maintenance packets are allowed.
+-- outputPortEnable_i - Activate the output port for non-maintenance packets.
+-- If deasserted, only non-maintenance packets are allowed.
+--
+-- This interface makes it possible to read and write ackId in both outbound
+-- and inbound directions. All input signals are validated by localAckIdWrite.
+-- localAckIdWrite_i - Indicate if a localAckId write operation is ongoing.
+-- Usually this signal is high one tick.
+-- clrOutstandingAckId_i - Clear outstanding ackId, i.e. reset the transmission
+-- window. The signal is only read if localAckIdWrite_i is high.
+-- inboundAckId_i - The value to set the inbound ackId (the ackId that the
+-- next inbound packet should have) to. This signal is only read if localAckIdWrite
+-- is high.
+-- outstandingAckId_i - The value to set the outstanding ackId (the ackId
+-- transmitted but not acknowledged) to. This signal is only read if localAckIdWrite
+-- is high.
+-- outboundAckId_i - The value to set the outbound ackId (the ackId that the
+-- next outbound packet will have) to. This signal is only read if localAckIdWrite
+-- is high.
+-- inboundAckId_o - The current inbound ackId.
+-- outstandingAckId_o - The current outstanding ackId.
+-- outboundAckId_o - The current outbound ackId.
+--
+-- This is the interface to the packet buffering sublayer.
+-- The window signals are used to send packets without removing them from the
+-- memory storage. This way, many packet can be sent without awaiting
+-- packet-accepted symbols and if a packet-accepted gets lost, it is possible
+-- to revert and resend a packet. This is achived by reading readWindowEmpty
+-- for new packet and asserting readWindowNext when a packet has been sent.
+-- When the packet-accepted is received, readFrame should be asserted to remove the
+-- packet from the storage. If a packet-accepted is missing, readWindowReset is
+-- asserted to set the current packet to read to the one that has not received
+-- a packet-accepted.
+-- readFrameEmpty_i - Indicate if a packet is ready in the outbound direction.
+-- Once deasserted, it is possible to read the packet content using
+-- readContent_o to update readContentData and readContentEnd.
+-- readFrame_o - Assert this signal for one tick to discard the oldest packet.
+-- It should be used when a packet has been fully read, a linkpartner has
+-- accepted it and the resources occupied by it should be returned to be
+-- used for new packets.
+-- readFrameRestart_o - Assert this signal to restart the reading of the
+-- current packet. readContentData and readContentEnd will be reset to the
+-- first content of the packet.
+-- readFrameAborted_i - This signal is asserted if the current packet was
+-- aborted while it was written. It is used when a transmitter starts to send a
+-- packet before it has been fully received and it is cancelled before it is
+-- completed. A one tick asserted readFrameRestart signal resets this signal.
+-- readWindowEmpty_i - Indicate if there are more packets to send.
+-- readWindowReset_o - Reset the current packet to the oldest stored in the memory.
+-- readWindowNext_o - Indicate that a new packet should be read. Must only be
+-- asserted if readWindowEmpty is deasserted. It should be high for one tick.
+-- readContentEmpty_i - Indicate if there are any packet content to be read.
+-- This signal is updated directly when packet content is written making it
+-- possible to read packet content before the full packet has been written to
+-- the memory storage.
+-- readContent_o - Update readContentData and readContentEnd.
+-- readContentEnd_i - Indicate if the end of the current packet has been
+-- reached. When asserted, readContentData is not valid.
+-- readContentData_i - The content of the current packet.
+-- writeFrameFull_i - Indicate if the inbound packet storage is ready to accept
+-- a new packet.
+-- writeFrame_o - Indicate that a new complete inbound packet has been written.
+-- writeFrameAbort_o - Indicate that the current packet is aborted and that all
+-- data written for this packet should be discarded.
+-- writeContent_o - Indicate that writeContentData is valid and should be
+-- written into the packet content storage.
+-- writeContentData_o - The content to write to the packet content storage.
+--
+-- This is the interface to the PCS (Physical Control Sublayer). Four types of
+-- symbols exist, idle, control, data and error.
+-- Idle symbols are transmitted when nothing else can be transmitted. They are
+-- mainly intended to enforce a timing on the transmitted symbols. This is
+-- needed to be able to guarantee that a status-control-symbol is transmitted
+-- at least once every 256 symbol.
+-- Control symbols contain control-symbols as described by the standard.
+-- Data symbols contains a 32-bit fragment of a RapidIO packet.
+-- Error symbols indicate that a corrupted symbol was received. This could be
+-- used by a PCS layer to indicate that a transmission error was detected and
+-- that the above layers should send link-requests to ensure the synchronism
+-- between the link-partners.
+-- The signals in this interface are:
+-- portInitialized_i - An asserted signal on this pin indicates that the PCS
+-- layer has established synchronization with the link and is ready to accept
+-- symbols.
+-- outboundSymbolEmpty_o - An asserted signal indicates that there are no
+-- outbound symbols to read. Once deasserted, outboundSymbol_o will be
+-- already be valid. This signal will be updated one tick after
+-- outboundSymbolRead_i has been asserted.
+-- outboundSymbolRead_i - Indicate that outboundSymbol_o has been read and a
+-- new value could be accepted. It should be active for one tick.
+-- outboundSymbol_o - The outbound symbol. The two MSB bits are the type of the
+-- symbol.
+-- bit 34-33
+-- 00=IDLE, the rest of the bits are not used.
+-- 01=CONTROL, the control symbols payload (24 bits) are placed in the MSB
+-- part of the symbol data.
+-- 10=ERROR, the rest of the bits are not used.
+-- 11=DATA, all the remaining bits contain the data-symbol payload.
+-- inboundSymbolFull_o - An asserted signal indicates that no more inbound
+-- symbols can be accepted.
+-- inboundSymbolWrite_i - Indicate that inboundSymbol_i contains valid
+-- information that should be forwarded. Should be active for one tick.
+-- inboundSymbol_i - The inbound symbol. See outboundSymbol_o for formating.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioSerial.
+-------------------------------------------------------------------------------
+entity RioSerial is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ -- System signals.
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals for maintenance operations.
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ linkInitialized_o : out std_logic;
+ inputPortEnable_i : in std_logic;
+ outputPortEnable_i : in std_logic;
+
+ -- Support for portLocalAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Outbound frame interface.
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ -- Inbound frame interface.
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ -- PCS layer signals.
+ portInitialized_i : in std_logic;
+ outboundSymbolEmpty_o : out std_logic;
+ outboundSymbolRead_i : in std_logic;
+ outboundSymbol_o : out std_logic_vector(33 downto 0);
+ inboundSymbolFull_o : out std_logic;
+ inboundSymbolWrite_i : in std_logic;
+ inboundSymbol_i : in std_logic_vector(33 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSerial.
+-------------------------------------------------------------------------------
+architecture RioSerialImpl of RioSerial is
+
+ component RioFifo1 is
+ generic(
+ WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(WIDTH-1 downto 0));
+ end component;
+
+ component RioTransmitter is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ portEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ portInitialized_i : in std_logic;
+ txFull_i : in std_logic;
+ txWrite_o : out std_logic;
+ txControl_o : out std_logic_vector(1 downto 0);
+ txData_o : out std_logic_vector(31 downto 0);
+
+ txControlEmpty_i : in std_logic;
+ txControlSymbol_i : in std_logic_vector(12 downto 0);
+ txControlUpdate_o : out std_logic;
+ rxControlEmpty_i : in std_logic;
+ rxControlSymbol_i : in std_logic_vector(12 downto 0);
+ rxControlUpdate_o : out std_logic;
+
+ linkInitialized_i : in std_logic;
+ linkInitialized_o : out std_logic;
+ ackIdStatus_i : in std_logic_vector(4 downto 0);
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0));
+ end component;
+
+ component RioReceiver is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portEnable_i : in std_logic;
+
+ localAckIdWrite_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+
+ portInitialized_i : in std_logic;
+ rxEmpty_i : in std_logic;
+ rxRead_o : out std_logic;
+ rxControl_i : in std_logic_vector(1 downto 0);
+ rxData_i : in std_logic_vector(31 downto 0);
+
+ txControlWrite_o : out std_logic;
+ txControlSymbol_o : out std_logic_vector(12 downto 0);
+ rxControlWrite_o : out std_logic;
+ rxControlSymbol_o : out std_logic_vector(12 downto 0);
+
+ ackIdStatus_o : out std_logic_vector(4 downto 0);
+ linkInitialized_o : out std_logic;
+
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+ end component;
+
+ signal linkInitializedRx : std_logic;
+ signal linkInitializedTx : std_logic;
+ signal ackIdStatus : std_logic_vector(4 downto 0);
+
+ signal txControlWrite : std_logic;
+ signal txControlWriteSymbol : std_logic_vector(12 downto 0);
+ signal txControlReadEmpty : std_logic;
+ signal txControlRead : std_logic;
+ signal txControlReadSymbol : std_logic_vector(12 downto 0);
+
+ signal rxControlWrite : std_logic;
+ signal rxControlWriteSymbol : std_logic_vector(12 downto 0);
+ signal rxControlReadEmpty : std_logic;
+ signal rxControlRead : std_logic;
+ signal rxControlReadSymbol : std_logic_vector(12 downto 0);
+
+ signal outboundFull : std_logic;
+ signal outboundWrite : std_logic;
+ signal outboundControl : std_logic_vector(1 downto 0);
+ signal outboundData : std_logic_vector(31 downto 0);
+ signal outboundSymbol : std_logic_vector(33 downto 0);
+
+ signal inboundEmpty : std_logic;
+ signal inboundRead : std_logic;
+ signal inboundControl : std_logic_vector(1 downto 0);
+ signal inboundData : std_logic_vector(31 downto 0);
+ signal inboundSymbol : std_logic_vector(33 downto 0);
+
+begin
+
+ linkInitialized_o <=
+ '1' when ((linkInitializedRx = '1') and (linkInitializedTx = '1')) else '0';
+
+ -----------------------------------------------------------------------------
+ -- Serial layer modules.
+ -----------------------------------------------------------------------------
+
+ Transmitter: RioTransmitter
+ generic map(
+ TIMEOUT_WIDTH=>TIMEOUT_WIDTH)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portLinkTimeout_i=>portLinkTimeout_i,
+ portEnable_i=>outputPortEnable_i,
+ localAckIdWrite_i=>localAckIdWrite_i,
+ clrOutstandingAckId_i=>clrOutstandingAckId_i,
+ outstandingAckId_i=>outstandingAckId_i,
+ outboundAckId_i=>outboundAckId_i,
+ outstandingAckId_o=>outstandingAckId_o,
+ outboundAckId_o=>outboundAckId_o,
+ portInitialized_i=>portInitialized_i,
+ txFull_i=>outboundFull, txWrite_o=>outboundWrite,
+ txControl_o=>outboundControl, txData_o=>outboundData,
+ txControlEmpty_i=>txControlReadEmpty, txControlSymbol_i=>txControlReadSymbol,
+ txControlUpdate_o=>txControlRead,
+ rxControlEmpty_i=>rxControlReadEmpty, rxControlSymbol_i=>rxControlReadSymbol,
+ rxControlUpdate_o=>rxControlRead,
+ linkInitialized_o=>linkInitializedTx,
+ linkInitialized_i=>linkInitializedRx, ackIdStatus_i=>ackIdStatus,
+ readFrameEmpty_i=>readFrameEmpty_i, readFrame_o=>readFrame_o,
+ readFrameRestart_o=>readFrameRestart_o, readFrameAborted_i=>readFrameAborted_i,
+ readWindowEmpty_i=>readWindowEmpty_i,
+ readWindowReset_o=>readWindowReset_o, readWindowNext_o=>readWindowNext_o,
+ readContentEmpty_i=>readContentEmpty_i, readContent_o=>readContent_o,
+ readContentEnd_i=>readContentEnd_i, readContentData_i=>readContentData_i);
+
+ TxSymbolFifo: RioFifo1
+ generic map(WIDTH=>13)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>txControlReadEmpty, read_i=>txControlRead, data_o=>txControlReadSymbol,
+ full_o=>open, write_i=>txControlWrite, data_i=>txControlWriteSymbol);
+
+ RxSymbolFifo: RioFifo1
+ generic map(WIDTH=>13)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>rxControlReadEmpty, read_i=>rxControlRead, data_o=>rxControlReadSymbol,
+ full_o=>open, write_i=>rxControlWrite, data_i=>rxControlWriteSymbol);
+
+ Receiver: RioReceiver
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portEnable_i=>inputPortEnable_i,
+ localAckIdWrite_i=>localAckIdWrite_i,
+ inboundAckId_i=>inboundAckId_i,
+ inboundAckId_o=>inboundAckId_o,
+ portInitialized_i=>portInitialized_i,
+ rxEmpty_i=>inboundEmpty, rxRead_o=>inboundRead,
+ rxControl_i=>inboundControl, rxData_i=>inboundData,
+ txControlWrite_o=>txControlWrite, txControlSymbol_o=>txControlWriteSymbol,
+ rxControlWrite_o=>rxControlWrite, rxControlSymbol_o=>rxControlWriteSymbol,
+ ackIdStatus_o=>ackIdStatus,
+ linkInitialized_o=>linkInitializedRx,
+ writeFrameFull_i=>writeFrameFull_i,
+ writeFrame_o=>writeFrame_o, writeFrameAbort_o=>writeFrameAbort_o,
+ writeContent_o=>writeContent_o, writeContentData_o=>writeContentData_o);
+
+ -----------------------------------------------------------------------------
+ -- PCS layer FIFO interface.
+ -----------------------------------------------------------------------------
+
+ outboundSymbol <= outboundControl & outboundData;
+ OutboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>outboundSymbolEmpty_o, read_i=>outboundSymbolRead_i, data_o=>outboundSymbol_o,
+ full_o=>outboundFull, write_i=>outboundWrite, data_i=>outboundSymbol);
+
+ inboundControl <= inboundSymbol(33 downto 32);
+ inboundData <= inboundSymbol(31 downto 0);
+ InboundSymbolFifo: RioFifo1
+ generic map(WIDTH=>34)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ empty_o=>inboundEmpty, read_i=>inboundRead, data_o=>inboundSymbol,
+ full_o=>inboundSymbolFull_o, write_i=>inboundSymbolWrite_i, data_i=>inboundSymbol_i);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- RioTransmitter
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioTransmitter.
+-------------------------------------------------------------------------------
+entity RioTransmitter is
+ generic(
+ TIMEOUT_WIDTH : natural);
+ port(
+ -- System signals.
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals used for maintenance.
+ portLinkTimeout_i : in std_logic_vector(TIMEOUT_WIDTH-1 downto 0);
+ portEnable_i : in std_logic;
+
+ -- Support for localAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ clrOutstandingAckId_i : in std_logic;
+ outstandingAckId_i : in std_logic_vector(4 downto 0);
+ outboundAckId_i : in std_logic_vector(4 downto 0);
+ outstandingAckId_o : out std_logic_vector(4 downto 0);
+ outboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Port output interface.
+ portInitialized_i : in std_logic;
+ txFull_i : in std_logic;
+ txWrite_o : out std_logic;
+ txControl_o : out std_logic_vector(1 downto 0);
+ txData_o : out std_logic_vector(31 downto 0);
+
+ -- Control symbols aimed to the transmitter.
+ txControlEmpty_i : in std_logic;
+ txControlSymbol_i : in std_logic_vector(12 downto 0);
+ txControlUpdate_o : out std_logic;
+
+ -- Control symbols from the receiver to send.
+ rxControlEmpty_i : in std_logic;
+ rxControlSymbol_i : in std_logic_vector(12 downto 0);
+ rxControlUpdate_o : out std_logic;
+
+ -- Internal signalling from the receiver part.
+ linkInitialized_o : out std_logic;
+ linkInitialized_i : in std_logic;
+ ackIdStatus_i : in std_logic_vector(4 downto 0);
+
+ -- Frame buffer interface.
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readFrameRestart_o : out std_logic;
+ readFrameAborted_i : in std_logic;
+ readWindowEmpty_i : in std_logic;
+ readWindowReset_o : out std_logic;
+ readWindowNext_o : out std_logic;
+ readContentEmpty_i : in std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioTransmitter.
+-------------------------------------------------------------------------------
+architecture RioTransmitterImpl of RioTransmitter is
+
+ constant NUMBER_STATUS_TRANSMIT : natural := 15;
+ constant NUMBER_LINK_RESPONSE_RETRIES : natural := 2;
+
+ component MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1;
+ INIT_VALUE : std_logic := 'U');
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component Crc5ITU is
+ port(
+ d_i : in std_logic_vector(18 downto 0);
+ crc_o : out std_logic_vector(4 downto 0));
+ end component;
+
+ type StateType is (STATE_UNINITIALIZED, STATE_PORT_INITIALIZED,
+ STATE_NORMAL,
+ STATE_OUTPUT_RETRY_STOPPED,
+ STATE_SEND_LINK_REQUEST, STATE_OUTPUT_ERROR_STOPPED,
+ STATE_RECOVER, STATE_FATAL_ERROR);
+ signal stateCurrent, stateNext : StateType;
+
+ signal statusReceivedCurrent, statusReceivedNext : std_logic;
+ signal counterCurrent, counterNext : natural range 0 to 15;
+ signal symbolsTransmittedCurrent, symbolsTransmittedNext : natural range 0 to 255;
+
+ type FrameStateType is (FRAME_START, FRAME_CHECK, FRAME_ACKID, FRAME_BODY, FRAME_END);
+ signal frameStateCurrent, frameStateNext : FrameStateType;
+ signal ackIdCurrent, ackIdNext : unsigned(4 downto 0) := (others=>'0');
+ signal ackIdWindowCurrent, ackIdWindowNext : unsigned(4 downto 0) := (others=>'0');
+ signal bufferStatusCurrent, bufferStatusNext : std_logic_vector(4 downto 0);
+
+ signal stype0 : std_logic_vector(2 downto 0);
+ signal parameter0 : std_logic_vector(4 downto 0);
+ signal parameter1 : std_logic_vector(4 downto 0);
+ signal stype1 : std_logic_vector(2 downto 0);
+ signal cmd : std_logic_vector(2 downto 0);
+
+ signal txControlStype0 : std_logic_vector(2 downto 0);
+ signal txControlParameter0 : std_logic_vector(4 downto 0);
+ signal txControlParameter1 : std_logic_vector(4 downto 0);
+
+ signal rxControlStype0 : std_logic_vector(2 downto 0);
+ signal rxControlParameter0 : std_logic_vector(4 downto 0);
+ signal rxControlParameter1 : std_logic_vector(4 downto 0);
+
+ signal symbolWrite : std_logic;
+ signal symbolType : std_logic_vector(1 downto 0);
+ signal symbolControl : std_logic_vector(31 downto 0);
+ signal symbolData : std_logic_vector(31 downto 0);
+ signal crcCalculated : std_logic_vector(4 downto 0);
+
+ signal timeoutWrite : std_logic;
+ signal timeoutCounter : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutFrame : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutElapsed : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutDelta : unsigned(TIMEOUT_WIDTH downto 0);
+ signal timeoutExpired : std_logic;
+
+ signal timeoutAddress : std_logic_vector(4 downto 0);
+ signal timeoutMemoryOut : std_logic_vector(TIMEOUT_WIDTH downto 0);
+
+begin
+
+ linkInitialized_o <= '0' when ((stateCurrent = STATE_UNINITIALIZED) or
+ (stateCurrent = STATE_PORT_INITIALIZED)) else '1';
+
+ -----------------------------------------------------------------------------
+ -- Assign control symbol from fifo signals.
+ -----------------------------------------------------------------------------
+
+ txControlStype0 <= txControlSymbol_i(12 downto 10);
+ txControlParameter0 <= txControlSymbol_i(9 downto 5);
+ txControlParameter1 <= txControlSymbol_i(4 downto 0);
+
+ rxControlStype0 <= rxControlSymbol_i(12 downto 10);
+ rxControlParameter0 <= rxControlSymbol_i(9 downto 5);
+ rxControlParameter1 <= rxControlSymbol_i(4 downto 0);
+
+ -----------------------------------------------------------------------------
+ -- Outbound symbol creation logic.
+ -----------------------------------------------------------------------------
+
+ symbolControl(31 downto 29) <= stype0;
+ symbolControl(28 downto 24) <= parameter0;
+ symbolControl(23 downto 19) <= parameter1;
+ symbolControl(18 downto 16) <= stype1;
+ symbolControl(15 downto 13) <= cmd;
+ symbolControl(12 downto 8) <= crcCalculated;
+ symbolControl(7 downto 0) <= x"00";
+
+ Crc5Calculator: Crc5ITU
+ port map(
+ d_i=>symbolControl(31 downto 13), crc_o=>crcCalculated);
+
+ txWrite_o <= symbolWrite;
+ txControl_o <= symbolType;
+ txData_o <= symbolControl when (symbolType = SYMBOL_CONTROL) else symbolData;
+
+ -----------------------------------------------------------------------------
+ -- Packet timeout logic.
+ -----------------------------------------------------------------------------
+
+ -- Note that the timer is one bit larger to be able to detect a timeout on a
+ -- free-running counter.
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ timeoutCounter <= (others=>'0');
+ elsif (clk'event and clk = '1') then
+ timeoutCounter <= timeoutCounter + 1;
+ end if;
+ end process;
+
+ timeoutElapsed <= timeoutCounter - timeoutFrame;
+ timeoutDelta <= unsigned('0' & portLinkTimeout_i) - timeoutElapsed;
+ timeoutExpired <= timeoutDelta(TIMEOUT_WIDTH);
+
+ timeoutFrame <= unsigned(timeoutMemoryOut);
+ TimeoutMemory: MemorySimpleDualPortAsync
+ generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>TIMEOUT_WIDTH+1, INIT_VALUE=>'0')
+ port map(
+ clkA_i=>clk, enableA_i=>timeoutWrite,
+ addressA_i=>timeoutAddress, dataA_i=>std_logic_vector(timeoutCounter),
+ addressB_i=>std_logic_vector(ackIdCurrent), dataB_o=>timeoutMemoryOut);
+
+ -----------------------------------------------------------------------------
+ -- Main outbound symbol handler, synchronous part.
+ -----------------------------------------------------------------------------
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ stateCurrent <= STATE_UNINITIALIZED;
+
+ statusReceivedCurrent <= '0';
+ counterCurrent <= 0;
+ symbolsTransmittedCurrent <= 0;
+
+ frameStateCurrent <= FRAME_START;
+ ackIdCurrent <= (others => '0');
+ ackIdWindowCurrent <= (others => '0');
+ bufferStatusCurrent <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ stateCurrent <= stateNext;
+
+ statusReceivedCurrent <= statusReceivedNext;
+ counterCurrent <= counterNext;
+ symbolsTransmittedCurrent <= symbolsTransmittedNext;
+
+ frameStateCurrent <= frameStateNext;
+ ackIdCurrent <= ackIdNext;
+ ackIdWindowCurrent <= ackIdWindowNext;
+ bufferStatusCurrent <= bufferStatusNext;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Main outbound symbol handler, combinatorial part.
+ -----------------------------------------------------------------------------
+ process(stateCurrent,
+ statusReceivedCurrent, counterCurrent,
+ symbolsTransmittedCurrent,
+ frameStateCurrent, ackIdCurrent, ackIdWindowCurrent, bufferStatusCurrent,
+ txControlStype0, txControlParameter0, txControlParameter1,
+ rxControlStype0, rxControlParameter0, rxControlParameter1,
+ portEnable_i,
+ localAckIdWrite_i, clrOutstandingAckId_i,
+ outstandingAckId_i, outboundAckId_i,
+ txFull_i,
+ txControlEmpty_i, txControlSymbol_i,
+ rxControlEmpty_i, rxControlSymbol_i,
+ portInitialized_i, linkInitialized_i, ackIdStatus_i,
+ readFrameEmpty_i, readFrameAborted_i,
+ readWindowEmpty_i,
+ readContentEmpty_i, readContentEnd_i, readContentData_i,
+ timeoutExpired)
+ begin
+ stateNext <= stateCurrent;
+ statusReceivedNext <= statusReceivedCurrent;
+ counterNext <= counterCurrent;
+ symbolsTransmittedNext <= symbolsTransmittedCurrent;
+
+ frameStateNext <= frameStateCurrent;
+ ackIdNext <= ackIdCurrent;
+ ackIdWindowNext <= ackIdWindowCurrent;
+ bufferStatusNext <= bufferStatusCurrent;
+
+ txControlUpdate_o <= '0';
+ rxControlUpdate_o <= '0';
+
+ readFrame_o <= '0';
+ readFrameRestart_o <= '0';
+ readWindowReset_o <= '0';
+ readWindowNext_o <= '0';
+ readContent_o <= '0';
+
+ symbolWrite <= '0';
+ symbolType <= (others=>'U');
+ stype0 <= (others=>'U');
+ parameter0 <= (others=>'U');
+ parameter1 <= (others=>'U');
+ stype1 <= (others=>'U');
+ cmd <= (others=>'U');
+ symbolData <= (others=>'U');
+
+ timeoutWrite <= '0';
+ timeoutAddress <= (others=>'U');
+
+ outstandingAckId_o <= std_logic_vector(ackIdCurrent);
+ outboundAckId_o <= std_logic_vector(ackIdWindowCurrent);
+
+ -- Check if a localAckIdWrite is active.
+ if (localAckIdWrite_i = '1') then
+ -- A localAckIdWrite is active.
+
+ -- Check if all outstanding packets should be discarded.
+ if (clrOutstandingAckId_i = '1') then
+ -- Delete all outbound packets.
+ -- REMARK: Remove all packets in another way... what if uninitialized???
+ stateNext <= STATE_RECOVER;
+ end if;
+
+ -- Set ackIds.
+ ackIdNext <= unsigned(outstandingAckId_i);
+ ackIdWindowNext <= unsigned(outboundAckId_i);
+ else
+ -- A localAckIdWrite is not active.
+
+ -- Act on the current state.
+ case (stateCurrent) is
+
+ when STATE_UNINITIALIZED =>
+ -----------------------------------------------------------------------
+ -- This state is entered at startup. A port that is not initialized
+ -- should only transmit idle sequences.
+ -----------------------------------------------------------------------
+
+ -- Check if the port is initialized.
+ if (portInitialized_i = '0') then
+ -- Port not initialized.
+
+ -- Check if any new symbols from the link partner has been received.
+ if (txControlEmpty_i = '0') then
+ -- New symbols have been received.
+ -- Discard all new symbols in this state.
+ txControlUpdate_o <= '1';
+ else
+ -- No new symbols from the link partner.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols should be transmitted to the link partner.
+ if (rxControlEmpty_i = '0') then
+ -- New symbols should be transmitted.
+ -- Do not forward any symbols in this state.
+ rxControlUpdate_o <= '1';
+ else
+ -- No new symbols to transmit.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new symbol should be transmitted.
+ if (txFull_i = '0') then
+ -- A new symbol should be transmitted.
+
+ -- Send idle sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+ else
+ -- The outbound fifo is full.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new full packet is ready.
+ if (readFrameEmpty_i = '0') then
+ -- A new full packet is ready.
+ -- It is not possible to send the packet now. If the packet is not
+ -- discarded it might congest the full system if the link does not
+ -- go initialized. To avoid a congested switch, the packet is
+ -- discarded and will have to be resent by the source when the link
+ -- is up and running.
+ readFrame_o <= '1';
+ else
+ -- No new full packets are ready.
+ -- Dont do anything.
+ end if;
+ else
+ -- Port is initialized.
+
+ -- Go to the initialized state and reset the counters.
+ statusReceivedNext <= '0';
+ counterNext <= NUMBER_STATUS_TRANSMIT;
+ symbolsTransmittedNext <= 0;
+ stateNext <= STATE_PORT_INITIALIZED;
+ end if;
+
+ when STATE_PORT_INITIALIZED =>
+ -----------------------------------------------------------------------
+ -- The specification requires a status control symbol being sent at
+ -- least every 1024 code word until an error-free status has been
+ -- received. This implies that at most 256 idle sequences should be
+ -- sent in between status control symbols. Once an error-free status has
+ -- been received, status symbols may be sent more rapidly. At least 15
+ -- statuses has to be transmitted once an error-free status has been
+ -- received.
+ ---------------------------------------------------------------------
+
+ -- Check if the port is initialized.
+ if (portInitialized_i = '1') then
+ -- Port is initialized.
+
+ -- Check if we are ready to change state to linkInitialized.
+ if ((linkInitialized_i = '1') and (counterCurrent = 0)) then
+ -- Receiver has received enough error free status symbols and we have
+ -- transmitted enough.
+
+ -- Initialize framing before entering the normal state.
+ ackIdWindowNext <= ackIdCurrent;
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+
+ -- Considder the link initialized.
+ stateNext <= STATE_NORMAL;
+ else
+ -- Not ready to change state to linkInitialized.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols from the link partner has been received.
+ if (txControlEmpty_i = '0') then
+ -- New symbols have been received.
+
+ -- Check if the new symbol is a status.
+ if (txControlStype0 = STYPE0_STATUS) then
+ -- A new status control symbol has been received.
+ statusReceivedNext <= '1';
+
+ -- Set the ackId and the linkpartner buffer status to what is indicated
+ -- in the received control symbol.
+ ackIdNext <= unsigned(txControlParameter0);
+ bufferStatusNext <= txControlParameter1;
+ else
+ -- Did not receive a status control symbol.
+ -- Discard it.
+ end if;
+
+ -- Update to the next control symbol received by the receiver.
+ txControlUpdate_o <= '1';
+ else
+ -- No new symbols from the link partner.
+ -- Dont do anything.
+ end if;
+
+ -- Check if any new symbols should be transmitted to the link partner.
+ if (rxControlEmpty_i = '0') then
+ -- New symbols should be transmitted.
+ -- Do not forward any symbols in this state.
+ rxControlUpdate_o <= '1';
+ else
+ -- No new symbols to transmit.
+ -- Dont do anything.
+ end if;
+
+ -- Check if a new symbol may be transmitted.
+ if (txFull_i = '0') then
+ -- A new symbol can be transmitted.
+
+ -- Check if idle sequence or a status symbol should be transmitted.
+ if (((statusReceivedCurrent = '0') and (symbolsTransmittedCurrent = 255)) or
+ ((statusReceivedCurrent = '1') and (symbolsTransmittedCurrent > 15))) then
+ -- A status symbol should be transmitted.
+
+ -- Send a status control symbol to the link partner.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Reset idle sequence transmission counter.
+ symbolsTransmittedNext <= 0;
+
+ -- Check if the number of transmitted statuses should be updated.
+ if (statusReceivedCurrent = '1') and (counterCurrent /= 0) then
+ counterNext <= counterCurrent - 1;
+ end if;
+ else
+ -- A idle sequence should be transmitted.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- Increment the idle sequence transmission counter.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- Cannot send a new symbol.
+ -- Dont do anything.
+ end if;
+ else
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_NORMAL =>
+ -------------------------------------------------------------------
+ -- This state is the normal state. It relays frames and handle flow
+ -- control.
+ -------------------------------------------------------------------
+
+ -- Check that both the port and link is initialized.
+ if (portInitialized_i = '1') and (linkInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if any control symbol has been received from the link
+ -- partner.
+ if (txControlEmpty_i = '0') then
+ -- A control symbol has been received.
+
+ -- Check the received control symbol.
+ case txControlStype0 is
+
+ when STYPE0_STATUS =>
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ when STYPE0_PACKET_ACCEPTED =>
+ -- The link partner is accepting a frame.
+
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ -- Check if expecting this type of reply and that the ackId is
+ -- expected.
+ if ((ackIdCurrent /= ackIdWindowCurrent) and
+ (ackIdCurrent = unsigned(txControlParameter0))) then
+ -- The packet-accepted is expected and the ackId is the expected.
+ -- The frame has been accepted by the link partner.
+
+ -- Update to a new buffer and increment the ackId.
+ readFrame_o <= '1';
+ ackIdNext <= ackIdCurrent + 1;
+ else
+ -- Unexpected packet-accepted or packet-accepted for
+ -- unexpected ackId.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ end if;
+
+ when STYPE0_PACKET_RETRY =>
+ -- The link partner has asked for a frame retransmission.
+
+ -- Save the number of buffers in the link partner.
+ bufferStatusNext <= txControlParameter1;
+
+ -- Check if the ackId is the one expected.
+ if (ackIdCurrent = unsigned(txControlParameter0)) then
+ -- The ackId to retry is expected.
+ -- Go to the output-retry-stopped state.
+ stateNext <= STATE_OUTPUT_RETRY_STOPPED;
+ else
+ -- Unexpected ackId to retry.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ end if;
+
+ when STYPE0_PACKET_NOT_ACCEPTED =>
+ -- Packet was rejected by the link-partner.
+ -- REMARK: Indicate that this has happened to the outside...
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+
+ when STYPE0_LINK_RESPONSE =>
+ -- Dont expect or need a link-response in this state.
+ -- Discard it.
+
+ when STYPE0_VC_STATUS =>
+ -- Not supported.
+ -- Discard it.
+
+ when STYPE0_RESERVED =>
+ -- Not supported.
+ -- Discard it.
+
+ when STYPE0_IMPLEMENTATION_DEFINED =>
+ -- Not supported.
+ -- Discard it.
+
+ when others =>
+ null;
+ end case;
+
+ -- Indicate the control symbol has been processed.
+ txControlUpdate_o <= '1';
+ else
+ -- No control symbol has been received.
+
+ -- Check if the oldest frame timeout has expired.
+ if ((ackIdCurrent /= ackIdWindowCurrent) and
+ (timeoutExpired = '1')) then
+ -- There has been a timeout on a transmitted frame.
+
+ -- Send link-request.
+ counterNext <= NUMBER_LINK_RESPONSE_RETRIES;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ else
+ -- There has been no timeout.
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Check if there are any events from the receiver.
+ if (rxControlEmpty_i = '0') then
+ -- A symbol from the receiver should be transmitted.
+
+ -- Send the receiver symbol and a NOP.
+ -- REMARK: Combine this symbol with an STYPE1 to more effectivly
+ -- utilize the link.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= rxControlStype0;
+ parameter0 <= rxControlParameter0;
+ parameter1 <= rxControlParameter1;
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Remove the symbol from the fifo.
+ rxControlUpdate_o <= '1';
+
+ -- Check if the transmitted symbol contains status about
+ -- available buffers.
+ if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
+ (rxControlStype0 = STYPE0_PACKET_RETRY)) then
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- A symbol not containing the bufferStatus has been sent.
+ -- REMARK: symbolsTransmitted might overflow...
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- No events from the receiver.
+
+ -- Check if a status symbol must be sent.
+ if (symbolsTransmittedCurrent = 255) then
+ -- A status symbol must be sent.
+
+ -- Reset the number of transmitted symbols between statuses.
+ symbolsTransmittedNext <= 0;
+
+ -- Send status.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+ else
+ -- A status symbol does not have to be sent.
+
+ -- Check if a frame transfer is in progress.
+ case frameStateCurrent is
+
+ when FRAME_START =>
+ ---------------------------------------------------------------
+ -- No frame has been started.
+ ---------------------------------------------------------------
+
+ -- Wait for a new frame to arrive from the frame buffer,
+ -- for new buffers to be available at the link-partner
+ -- and also check that a maximum 31 frames are outstanding.
+ if ((readWindowEmpty_i = '0') and (bufferStatusCurrent /= "00000") and
+ ((ackIdWindowCurrent - ackIdCurrent) /= 31)) then
+ -- New data is available for transmission and there
+ -- is room to receive it at the other side.
+
+ -- Indicate that a control symbol has been sent to start the
+ -- transmission of the frame.
+ frameStateNext <= FRAME_CHECK;
+
+ -- Update the output from the frame buffer to contain the
+ -- data when it is read later.
+ readContent_o <= '1';
+ else
+ -- There are no frame data to send or the link partner has
+ -- no available buffers.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+
+ when FRAME_CHECK =>
+ -------------------------------------------------------
+ -- Check if we are allowed to transmit this packet.
+ -------------------------------------------------------
+
+ -- Check if this packet is allowed to be transmitted.
+ if ((portEnable_i = '1') or (readContentData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS)) then
+ -- The packet may be transmitted.
+
+ -- Indicate that a control symbol has been sent to start the
+ -- transmission of the frame.
+ frameStateNext <= FRAME_ACKID;
+
+ -- Send a control symbol to start the packet and a status to complete
+ -- the symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_START_OF_PACKET;
+ cmd <= "000";
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- The packet should be discarded.
+
+ -- Check that there are no outstanding packets that
+ -- has not been acknowledged.
+ if(ackIdWindowCurrent /= ackIdCurrent) then
+ -- There are packets that has not been acknowledged.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ else
+ -- No unacknowledged packets.
+ -- It is now safe to remove the unallowed frame.
+ readFrame_o <= '1';
+
+ -- Go back and send a new frame.
+ frameStateNext <= FRAME_START;
+ end if;
+ end if;
+
+ when FRAME_ACKID =>
+ ---------------------------------------------------------------
+ -- Send the first packet content containing our current
+ -- ackId.
+ ---------------------------------------------------------------
+
+ -- Write a new data symbol and fill in our ackId on the
+ -- packet.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_DATA;
+ symbolData <= std_logic_vector(ackIdWindowCurrent) & "0" & readContentData_i(25 downto 0);
+
+ -- Continue to send the rest of the body of the packet.
+ readContent_o <= '1';
+ frameStateNext <= FRAME_BODY;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+
+ when FRAME_BODY =>
+ ---------------------------------------------------------------
+ -- The frame has not been fully sent.
+ -- Send a data symbol.
+ ---------------------------------------------------------------
+ -- REMARK: Add support for partial frames...
+
+ -- Check if the frame is ending.
+ if (readContentEnd_i = '0') then
+ -- The frame is not ending.
+
+ -- Write a new data symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_DATA;
+ symbolData <= readContentData_i;
+
+ -- Continue to send the rest of the body of the packet.
+ readContent_o <= '1';
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ else
+ -- The frame is ending.
+
+ -- Update the window to the next frame.
+ -- It takes one tick for the output from the frame
+ -- buffer to get updated.
+ readWindowNext_o <= '1';
+
+ -- Proceed to check if there is another frame to start
+ -- with directly.
+ frameStateNext <= FRAME_END;
+ end if;
+
+ when FRAME_END =>
+ ---------------------------------------------------------------
+ -- A frame has ended and the window has been updated.
+ -- Check if the next symbol should end the frame or if a
+ -- new one should be started.
+ ---------------------------------------------------------------
+
+ -- Check if there is a new frame pending.
+ if (readWindowEmpty_i = '1') then
+ -- No new frame is pending.
+
+ -- Send a control symbol to end the packet.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_END_OF_PACKET;
+ cmd <= "000";
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ -- Update the window ackId.
+ ackIdWindowNext <= ackIdWindowCurrent + 1;
+
+ -- Start timeout supervision for transmitted frame.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdWindowCurrent);
+
+ -- Start a new frame the next time.
+ frameStateNext <= FRAME_START;
+
+ when others =>
+ ---------------------------------------------------------------
+ --
+ ---------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end if;
+ else
+ -- Wait for new storage in the transmission FIFO to become
+ -- available.
+ -- Dont do anything.
+ end if;
+ end if;
+ end if;
+ else
+ -- The port or the link has become uninitialized.
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_OUTPUT_RETRY_STOPPED =>
+ -----------------------------------------------------------------------
+ -- This is the output-retry-stopped state described in 5.9.1.5.
+ -----------------------------------------------------------------------
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Send a restart-from-retry control symbol to acknowledge the restart
+ -- of the frame.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_RESTART_FROM_RETRY;
+ cmd <= "000";
+
+ -- Make sure there wont be any timeout before the frame is
+ -- starting to be retransmitted.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdCurrent);
+
+ -- Restart the frame transmission.
+ ackIdWindowNext <= ackIdCurrent;
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+
+ -- Proceed back to the normal state.
+ stateNext <= STATE_NORMAL;
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ when STATE_SEND_LINK_REQUEST =>
+ -----------------------------------------------------------------------
+ -- Send a link-request symbol when the transmission fifo is ready. Then
+ -- always proceed to the output-error-state.
+ -----------------------------------------------------------------------
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Send a link-request symbol.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_LINK_REQUEST;
+ cmd <= LINK_REQUEST_CMD_INPUT_STATUS;
+
+ -- Write the current timer value.
+ timeoutWrite <= '1';
+ timeoutAddress <= std_logic_vector(ackIdCurrent);
+
+ -- Proceed to the output-error-stopped state.
+ stateNext <= STATE_OUTPUT_ERROR_STOPPED;
+
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ end if;
+
+ when STATE_OUTPUT_ERROR_STOPPED =>
+ -------------------------------------------------------------------
+ -- This state is the error stopped state described in 5.13.2.7.
+ -------------------------------------------------------------------
+
+ -- Check that both the port and link is initialized.
+ if (portInitialized_i = '1') and (linkInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if any control symbol has been received from the link
+ -- partner.
+ if (txControlEmpty_i = '0') then
+ -- A control symbol has been received.
+
+ -- Check the received control symbol.
+ case txControlStype0 is
+
+ when STYPE0_PACKET_ACCEPTED =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_PACKET_RETRY =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_PACKET_NOT_ACCEPTED =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_STATUS =>
+ -- Wait for a link-response.
+ -- Discard these.
+
+ when STYPE0_LINK_RESPONSE =>
+ -- Check if the link partner return value is acceptable.
+ if ((unsigned(txControlParameter0) - ackIdCurrent) <=
+ (ackIdWindowCurrent - ackIdCurrent)) then
+ -- Recoverable error.
+ -- Use the received ackId and recover by removing packets
+ -- that were received by the link-partner.
+ ackIdWindowNext <= unsigned(txControlParameter0);
+ stateNext <= STATE_RECOVER;
+ else
+ -- Totally out of sync.
+ stateNext <= STATE_FATAL_ERROR;
+ end if;
+
+ when STYPE0_VC_STATUS =>
+ -- Not supported.
+
+ when STYPE0_RESERVED =>
+ -- Not supported.
+
+ when STYPE0_IMPLEMENTATION_DEFINED =>
+ -- Not supported.
+
+ when others =>
+ null;
+ end case;
+
+ -- Indicate the control symbol has been processed.
+ txControlUpdate_o <= '1';
+ else
+ -- No control symbol has been received.
+
+ -- Check if the timeout for a link-response has expired.
+ if (timeoutExpired = '1') then
+ -- There was no reply on the link-request.
+
+ -- Count the number of retransmissions and abort if
+ -- no reply has been received for too many times.
+ if (counterCurrent /= 0) then
+ -- Not sent link-request too many times.
+
+ -- Send another link-request.
+ counterNext <= counterCurrent - 1;
+ stateNext <= STATE_SEND_LINK_REQUEST;
+ else
+ -- No response for too many times.
+ stateNext <= STATE_FATAL_ERROR;
+ end if;
+ else
+ -- There has been no timeout.
+
+ -- Check if the outbound fifo needs new data.
+ if (txFull_i = '0') then
+ -- There is room available in the outbound FIFO.
+
+ -- Check if there are any events from the receiver.
+ if (rxControlEmpty_i = '0') then
+ -- A symbol from the receiver should be transmitted.
+
+ -- Send the receiver symbol and a NOP.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= rxControlStype0;
+ parameter0 <= rxControlParameter0;
+ parameter1 <= rxControlParameter1;
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+
+ -- Remove the symbol from the fifo.
+ rxControlUpdate_o <= '1';
+
+ -- Check if the transmitted symbol contains status about
+ -- available buffers.
+ -- The receiver never send any status so that does not have
+ -- to be checked.
+ if ((rxControlStype0 = STYPE0_PACKET_ACCEPTED) or
+ (rxControlStype0 = STYPE0_PACKET_RETRY)) then
+ -- A symbol containing the bufferStatus has been sent.
+ symbolsTransmittedNext <= 0;
+ else
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ else
+ -- No events from the receiver.
+ -- There are no frame data to send or the link partner has
+ -- no available buffers.
+
+ -- Check if a status symbol must be sent.
+ if (symbolsTransmittedCurrent = 255) then
+ -- A status symbol must be sent.
+
+ -- Reset the number of transmitted symbols between statuses.
+ symbolsTransmittedNext <= 0;
+
+ -- Send status.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_CONTROL;
+ stype0 <= STYPE0_STATUS;
+ parameter0 <= ackIdStatus_i;
+ parameter1 <= "11111";
+ stype1 <= STYPE1_NOP;
+ cmd <= "000";
+ else
+ -- A status symbol does not have to be sent.
+
+ -- Send idle-sequence.
+ symbolWrite <= '1';
+ symbolType <= SYMBOL_IDLE;
+
+ -- A symbol not containing the buffer status has been sent.
+ symbolsTransmittedNext <= symbolsTransmittedCurrent + 1;
+ end if;
+ end if;
+ else
+ -- Wait for new storage in the transmission FIFO to become
+ -- available.
+ -- Dont do anything.
+ end if;
+ end if;
+ end if;
+ else
+ -- The port or the link has become uninitialized.
+ -- Go back to the uninitialized state.
+ stateNext <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_RECOVER =>
+ -----------------------------------------------------------------------
+ -- A recoverable error condition has occurred.
+ -- When this state is entered, ackIdWindow should contain the ackId to
+ -- proceed with.
+ -----------------------------------------------------------------------
+
+ -- Check if the expected ackId has incremented enough.
+ if (ackIdCurrent /= ackIdWindowCurrent) then
+ -- Remove this frame. It has been received by the link-partner.
+ readFrame_o <= '1';
+ ackIdNext <= ackIdCurrent + 1;
+ else
+ -- Keep this frame.
+ -- Restart the window and the frame transmission.
+ frameStateNext <= FRAME_START;
+ readWindowReset_o <= '1';
+ stateNext <= STATE_NORMAL;
+ end if;
+
+ when STATE_FATAL_ERROR =>
+ -----------------------------------------------------------------------
+ -- A fatal error condition has occurred.
+ -----------------------------------------------------------------------
+
+ -- Reset the window and resynchronize the link.
+ -- REMARK: Count these situations...
+ -- REMARK: Do something else here???
+ readWindowReset_o <= '1';
+ stateNext <= STATE_UNINITIALIZED;
+
+ when others =>
+ -------------------------------------------------------------------
+ --
+ -------------------------------------------------------------------
+ null;
+ end case;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity RioReceiver is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ -- Status signals used for maintenance.
+ portEnable_i : in std_logic;
+
+ -- Support for localAckIdCSR.
+ localAckIdWrite_i : in std_logic;
+ inboundAckId_i : in std_logic_vector(4 downto 0);
+ inboundAckId_o : out std_logic_vector(4 downto 0);
+
+ -- Port input interface.
+ portInitialized_i : in std_logic;
+ rxEmpty_i : in std_logic;
+ rxRead_o : out std_logic;
+ rxControl_i : in std_logic_vector(1 downto 0);
+ rxData_i : in std_logic_vector(31 downto 0);
+
+ -- Receiver has received a control symbol containing:
+ -- packet-accepted, packet-retry, packet-not-accepted,
+ -- status, VC_status, link-response
+ txControlWrite_o : out std_logic;
+ txControlSymbol_o : out std_logic_vector(12 downto 0);
+
+ -- Reciever wants to signal the link partner:
+ -- a new frame has been accepted => packet-accepted(rxAckId, bufferStatus)
+ -- a frame needs to be retransmitted due to buffering =>
+ -- packet-retry(rxAckId, bufferStatus)
+ -- a frame is rejected due to errors => packet-not-accepted
+ -- a link-request should be answered => link-response
+ rxControlWrite_o : out std_logic;
+ rxControlSymbol_o : out std_logic_vector(12 downto 0);
+
+ -- Status signals used internally.
+ ackIdStatus_o : out std_logic_vector(4 downto 0);
+ linkInitialized_o : out std_logic;
+
+ -- Frame buffering interface.
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture RioReceiverImpl of RioReceiver is
+
+ component Crc5ITU is
+ port(
+ d_i : in std_logic_vector(18 downto 0);
+ crc_o : out std_logic_vector(4 downto 0));
+ end component;
+
+ component Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+ end component;
+
+ type StateType is (STATE_UNINITIALIZED, STATE_PORT_INITIALIZED,
+ STATE_NORMAL,
+ STATE_INPUT_RETRY_STOPPED, STATE_INPUT_ERROR_STOPPED);
+ signal state : StateType;
+
+ signal statusCounter : natural range 0 to 8;
+
+ signal ackId : unsigned(4 downto 0);
+ signal frameIndex : natural range 0 to 70;
+
+ signal stype0 : std_logic_vector(2 downto 0);
+ signal parameter0 : std_logic_vector(4 downto 0);
+ signal parameter1 : std_logic_vector(4 downto 0);
+ signal stype1 : std_logic_vector(2 downto 0);
+ signal cmd : std_logic_vector(2 downto 0);
+
+ signal crc5 : std_logic_vector(4 downto 0);
+ signal crc5Calculated : std_logic_vector(4 downto 0);
+
+ signal crc16Valid : std_logic;
+ signal crc16Data : std_logic_vector(31 downto 0);
+ signal crc16Current : std_logic_vector(15 downto 0);
+ signal crc16Temp : std_logic_vector(15 downto 0);
+ signal crc16Next : std_logic_vector(15 downto 0);
+
+ signal rxRead : std_logic;
+
+begin
+
+ linkInitialized_o <= '0' when ((state = STATE_UNINITIALIZED) or
+ (state = STATE_PORT_INITIALIZED)) else '1';
+ ackIdStatus_o <= std_logic_vector(ackId);
+
+ -----------------------------------------------------------------------------
+ -- Get the entries in a control symbol.
+ -----------------------------------------------------------------------------
+
+ stype0 <= rxData_i(31 downto 29);
+ parameter0 <= rxData_i(28 downto 24);
+ parameter1 <= rxData_i(23 downto 19);
+ stype1 <= rxData_i(18 downto 16);
+ cmd <= rxData_i(15 downto 13);
+ crc5 <= rxData_i(12 downto 8);
+
+ -----------------------------------------------------------------------------
+ -- Entity for CRC-5 calculation on control symbols according to the standard.
+ -----------------------------------------------------------------------------
+
+ Crc5Calculator: Crc5ITU
+ port map(
+ d_i=>rxData_i(31 downto 13), crc_o=>crc5Calculated);
+
+ -----------------------------------------------------------------------------
+ -- Entities for CRC-16 calculation on 32-bit data in frames according to the
+ -- standard.
+ -----------------------------------------------------------------------------
+
+ -- If the CRC is correct, there is either zero in crc16Next if no pad exists
+ -- or zero in crc16Temp and crc16Data(15 downto 0). This means that crc16Next
+ -- will always be zero here if the CRC is correct.
+ crc16Valid <= '1' when (crc16Next = x"0000") else '0';
+
+ Crc16High: Crc16CITT
+ port map(
+ d_i=>crc16Data(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
+ Crc16Low: Crc16CITT
+ port map(
+ d_i=>crc16Data(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
+
+ -----------------------------------------------------------------------------
+ -- Main inbound symbol handler.
+ -----------------------------------------------------------------------------
+ rxRead_o <= rxRead;
+ inboundAckId_o <= std_logic_vector(ackId);
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ state <= STATE_UNINITIALIZED;
+
+ rxRead <= '0';
+ txControlWrite_o <= '0';
+ txControlSymbol_o <= (others => '0');
+ rxControlWrite_o <= '0';
+ rxControlSymbol_o <= (others => '0');
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+ writeContentData_o <= (others => '0');
+
+ -- REMARK: Use frameIndex instead of this...
+ statusCounter <= 0;
+
+ frameIndex <= 0;
+ ackId <= (others => '0');
+
+ crc16Current <= (others => '0');
+ crc16Data <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ rxRead <= '0';
+
+ txControlWrite_o <= '0';
+ rxControlWrite_o <= '0';
+
+ writeFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ writeContent_o <= '0';
+
+ -- Check if a locakAckIdWrite is active.
+ if (localAckIdWrite_i = '1') then
+ -- A localAckIdWrite is active.
+ -- Set ackId.
+ ackId <= unsigned(inboundAckId_i);
+ else
+ -- A localAckIdWrite is not active.
+
+ -- Act on the current state.
+ case state is
+
+ when STATE_UNINITIALIZED =>
+ -----------------------------------------------------------------------
+ -- This state is entered at startup. A port that is not initialized
+ -- should discard all received symbols.
+ -----------------------------------------------------------------------
+
+ -- Check if the port is initialized.
+ if (portInitialized_i = '0') then
+ -- Port not initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- New symbol ready.
+ -- Discard all received symbols in this state.
+ rxRead <= '1';
+ else
+ -- No new symbol ready to be read.
+ -- Dont do anything.
+ end if;
+ else
+ -- Port is initialized.
+
+ -- Go to the initialized state and reset the counters.
+ state <= STATE_PORT_INITIALIZED;
+ statusCounter <= 0;
+ end if;
+
+ when STATE_PORT_INITIALIZED =>
+ ---------------------------------------------------------------------
+ -- The port has been initialized and status control symbols are being
+ -- received on the link to check if it is working. Count the number
+ -- of error-free status symbols and considder the link initialized
+ -- when enough of them has been received. Frames are not allowed
+ -- here.
+ ---------------------------------------------------------------------
+
+ -- Check if the port is initialized.
+ if (portInitialized_i = '1') then
+ -- Port is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol that is not a packet delimiter.
+
+ -- Check if the control symbol has a valid checksum.
+ if (crc5Calculated = crc5) then
+ -- The control symbol has a valid checksum.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype0 part if we should count the number of
+ -- error-free status symbols.
+ if (stype0 = STYPE0_STATUS) then
+ -- The symbol is a status.
+
+ -- Check if enough status symbols have been received.
+ if (statusCounter = 7) then
+ -- Enough status symbols have been received.
+
+ -- Reset all packets.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Set the link as initialized.
+ state <= STATE_NORMAL;
+ else
+ -- Increase the number of error-free status symbols that
+ -- has been received.
+ statusCounter <= statusCounter + 1;
+ end if;
+ else
+ -- The symbol is not a status.
+ -- Dont do anything.
+ end if;
+ else
+ -- A control symbol with CRC5 error was recevied.
+ statusCounter <= 0;
+ end if;
+ else
+ -- Symbol that is not allowed in this state have been received.
+ -- Discard it.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol ready to be read.
+ -- Dont do anything.
+ end if;
+ else
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_NORMAL =>
+ ---------------------------------------------------------------------
+ -- The port has been initialized and enough error free status symbols
+ -- have been received. Forward data frames to the frame buffer
+ -- interface. This is the normal operational state.
+ ---------------------------------------------------------------------
+
+ -- Check that the port is initialized.
+ if (portInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_START_OF_PACKET =>
+ -------------------------------------------------------------
+ -- Start the reception of a new frame or end a currently
+ -- ongoing frame.
+ -------------------------------------------------------------
+
+ -- Check if a frame has already been started.
+ if (frameIndex /= 0) then
+ -- A frame is already started.
+ -- Complete the last frame and start to ackumulate a new one
+ -- and update the ackId.
+
+ -- Check the CRC-16 and the length of the received frame.
+ if (crc16Valid = '1') and (frameIndex > 3) then
+ -- The CRC-16 is ok.
+
+ -- Reset the frame index to indicate the frame is started.
+ frameIndex <= 1;
+
+ -- Update the frame buffer to indicate that the frame has
+ -- been completly received.
+ writeFrame_o <= '1';
+
+ -- Update ackId.
+ ackId <= ackId + 1;
+
+ -- Send packet-accepted.
+ -- The buffer status is appended by the transmitter
+ -- when sent to get the latest number.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_ACCEPTED & std_logic_vector(ackId) & "11111";
+ else
+ -- The CRC-16 is not ok.
+
+ -- Make the transmitter send a packet-not-accepted to indicate
+ -- that the received packet contained a CRC error.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- No frame has been started.
+
+ -- Reset the frame index to indicate the frame is started.
+ frameIndex <= 1;
+ end if;
+
+ when STYPE1_END_OF_PACKET =>
+ -------------------------------------------------------------
+ -- End the reception of an old frame.
+ -------------------------------------------------------------
+
+ -- Check the CRC-16 and the length of the received frame.
+ if (crc16Valid = '1') and (frameIndex > 3) then
+ -- The CRC-16 is ok.
+
+ -- Reset frame reception to indicate that no frame is ongoing.
+ frameIndex <= 0;
+
+ -- Update the frame buffer to indicate that the frame has
+ -- been completly received.
+ writeFrame_o <= '1';
+
+ -- Update ackId.
+ ackId <= ackId + 1;
+
+ -- Send packet-accepted.
+ -- The buffer status is appended by the transmitter
+ -- when sent to get the latest number.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_ACCEPTED & std_logic_vector(ackId) & "11111";
+ else
+ -- The CRC-16 is not ok.
+
+ -- Make the transmitter send a packet-not-accepted to indicate
+ -- that the received packet contained a CRC error.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_PACKET_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+
+ when STYPE1_STOMP =>
+ -------------------------------------------------------------
+ -- Restart the reception of an old frame.
+ -------------------------------------------------------------
+ -- See 5.10 in the standard.
+
+ -- Make the transmitter send a packet-retry to indicate
+ -- that the packet cannot be accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_RETRY & std_logic_vector(ackId) & "11111";
+
+ -- Enter the input retry-stopped state.
+ state <= STATE_INPUT_RETRY_STOPPED;
+
+ when STYPE1_RESTART_FROM_RETRY =>
+ -------------------------------------------------------------
+ -- The receiver indicates a restart from a retry sent
+ -- from us.
+ -------------------------------------------------------------
+ -- See 5.10 in the standard.
+ -- Protocol error, this symbol should not be received here since
+ -- we should have been in input-retry-stopped.
+
+ -- Send a packet-not-accepted to indicate that a protocol
+ -- error has occurred.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
+ state <= STATE_INPUT_ERROR_STOPPED;
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Reply to a LINK-REQUEST.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "10000";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ when STYPE1_MULTICAST_EVENT =>
+ -------------------------------------------------------------
+ -- Multicast symbol.
+ -------------------------------------------------------------
+ -- Discard the symbol.
+
+ when STYPE1_RESERVED =>
+ -------------------------------------------------------------
+ -- Reserved.
+ -------------------------------------------------------------
+ -- Not supported, dont do anything.
+
+ when STYPE1_NOP =>
+ -------------------------------------------------------------
+ -- NOP, no operation.
+ -------------------------------------------------------------
+ -- Dont do anything.
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- NOP, no operation, dont do anything.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+
+ -- Send a packet-not-accepted to indicate that a corrupted
+ -- control-symbol has been received and change state.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ elsif (rxControl_i = SYMBOL_DATA) then
+ -- This is a data symbol.
+ -- REMARK: Add check for in-the-middle-crc here...
+
+ -- Check if a frame has been started.
+ -- Index=0 not started
+ -- index=1 started and expecting to receive the first data.
+ -- index=others, the index of the received data.
+ if (frameIndex /= 0) and (frameIndex /= 70) then
+ -- A frame has been started and is not too long.
+
+ -- Check if the ackId is correct.
+ if (((frameIndex = 1) and (unsigned(rxData_i(31 downto 27)) = ackId)) or
+ (frameIndex /= 1)) then
+ -- This is the first data symbol containing the ackId which
+ -- is matching or receiving the rest of the frame.
+
+ -- Check if the packet ftype is allowed.
+ -- If the portEnable is deasserted only maintenance
+ -- packets are allowed.
+ if (((frameIndex = 1) and
+ ((portEnable_i = '1') or (rxData_i(19 downto 16) = FTYPE_MAINTENANCE_CLASS))) or
+ (frameIndex /= 1)) then
+ -- The packet is allowed.
+
+ -- Check if there is buffers available to store the new packet.
+ if(writeFrameFull_i = '0') then
+ -- There is buffering space available to store the new data.
+
+ -- Write the data to the frame FIFO.
+ writeContent_o <= '1';
+ writeContentData_o <= rxData_i;
+
+ -- Increment the number of received data symbols.
+ frameIndex <= frameIndex + 1;
+
+ -- Update the saved crc result with the output from the CRC calculation.
+ if (frameIndex = 1) then
+ -- Note that the ackId should not be included when the CRC
+ -- is calculated.
+ crc16Data <= "000000" & rxData_i(25 downto 0);
+ crc16Current <= (others => '1');
+ else
+ crc16Data <= rxData_i;
+ crc16Current <= crc16Next;
+ end if;
+ else
+ -- The packet buffer is full.
+ -- Let the link-partner resend the packet.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_RETRY & std_logic_vector(ackId) & "11111";
+ state <= STATE_INPUT_RETRY_STOPPED;
+ end if;
+ else
+ -- The non-maintenance packets are not allowed.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <=
+ STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_NON_MAINTENANCE_STOPPED;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- The ackId is unexpected.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <=
+ STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_UNEXPECTED_ACKID;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- A frame has not been started or is too long.
+ -- Send packet-not-accepted.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED & "00000" & PACKET_NOT_ACCEPTED_CAUSE_GENERAL_ERROR;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ else
+ -- Idle sequence received.
+ -- Discard these.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_INPUT_RETRY_STOPPED =>
+ ---------------------------------------------------------------------
+ -- This state is entered when a frame could not be accepted. All
+ -- symbols except restart-from-retry and link-request are discarded.
+ -- A restart-from-retry triggers a state change into the normal
+ -- link-initialized state.
+ ---------------------------------------------------------------------
+
+ -- Check that the port is initialized.
+ if (portInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_RESTART_FROM_RETRY =>
+ -------------------------------------------------------------
+ -- The receiver indicates a restart from a retry sent
+ -- from us.
+ -------------------------------------------------------------
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Received a link-request.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "00100";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- Discard other control symbols.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+
+ -- Send a packet-not-accepted to indicate that a corrupted
+ -- control-symbol has been received and change state.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_PACKET_NOT_ACCEPTED &
+ "00000" &
+ PACKET_NOT_ACCEPTED_CAUSE_CONTROL_CRC;
+ state <= STATE_INPUT_ERROR_STOPPED;
+ end if;
+ elsif (rxControl_i = SYMBOL_DATA) then
+ -- This is a data symbol.
+ -- Discard all data symbols in this state.
+ else
+ -- Idle sequence received.
+ -- Discard other symbols.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when STATE_INPUT_ERROR_STOPPED =>
+ ---------------------------------------------------------------------
+ -- This state is entered when an error situation has occurred. When in this
+ -- state, all symbols should be discarded until a link-request-symbols has
+ -- been received. See section 5.13.2.6 in part 6 of the standard.
+ -- Note that it is only the input side of the port that are affected, not the
+ -- output side. Packets may still be transmitted and acknowledges should be
+ -- accepted.
+ ---------------------------------------------------------------------
+
+ -- Check that the port is initialized.
+ if (portInitialized_i = '1') then
+ -- The port and link is initialized.
+
+ -- Check if a new symbol is ready to be read.
+ if (rxRead = '0') and (rxEmpty_i = '0') then
+ -- There is a new symbol to read.
+
+ -- Check the type of symbol.
+ if (rxControl_i = SYMBOL_CONTROL) then
+ -- This is a control symbol with or without a packet delimiter.
+
+ -- Check if the control symbol has a valid CRC-5.
+ if (crc5Calculated = crc5) then
+ -- The control symbol is correct.
+
+ -- Forward the stype0 part of the symbol to the transmitter.
+ txControlWrite_o <= '1';
+ txControlSymbol_o <= stype0 & parameter0 & parameter1;
+
+ -- Check the stype1 part.
+ case stype1 is
+
+ when STYPE1_LINK_REQUEST =>
+ -------------------------------------------------------------
+ -- Received a link-request.
+ -------------------------------------------------------------
+
+ -- Check the command part.
+ -- REMARK: Should also send a status-control-symbol
+ -- directly following this symbol...
+ if (cmd = "100") then
+ -- Return input port status command.
+ -- This functions as a link-request(restart-from-error)
+ -- control symbol under error situations.
+
+ -- Send a link response containing an ok reply.
+ rxControlWrite_o <= '1';
+ rxControlSymbol_o <= STYPE0_LINK_RESPONSE & std_logic_vector(ackId) & "00101";
+ elsif (cmd = "011") then
+ -- Reset device command.
+ -- Discard this.
+ else
+ -- Unsupported command.
+ -- Discard this.
+ end if;
+
+ -- Abort the frame and reset frame reception.
+ frameIndex <= 0;
+ writeFrameAbort_o <= '1';
+
+ -- Go back to the normal operational state.
+ state <= STATE_NORMAL;
+
+ when others =>
+ -------------------------------------------------------------
+ --
+ -------------------------------------------------------------
+ -- Discard other control symbols.
+ null;
+
+ end case;
+ else
+ -- The control symbol contains a crc error.
+ -- Error is ignored in this state.
+ end if;
+ else
+ -- Other symbol received.
+ -- All other symbols are discarded in this state.
+ end if;
+
+ -- Update to the next symbol.
+ rxRead <= '1';
+ else
+ -- No new symbol received.
+ -- Dont do anything.
+ end if;
+ else
+ -- The port has become uninitialized.
+ -- Go back to the uninitialized state.
+ state <= STATE_UNINITIALIZED;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ --
+ ---------------------------------------------------------------------
+ null;
+ end case;
+ end if;
+ end if;
+ end process;
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- A CRC-5 calculator following the implementation proposed in the 2.2
+-- standard.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+entity Crc5ITU is
+ port(
+ d_i : in std_logic_vector(18 downto 0);
+ crc_o : out std_logic_vector(4 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+--
+-------------------------------------------------------------------------------
+architecture Crc5Impl of Crc5ITU is
+ signal d : std_logic_vector(0 to 18);
+ signal c : std_logic_vector(0 to 4);
+
+begin
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ d(18) <= d_i(0); d(17) <= d_i(1); d(16) <= d_i(2); d(15) <= d_i(3);
+ d(14) <= d_i(4); d(13) <= d_i(5); d(12) <= d_i(6); d(11) <= d_i(7);
+ d(10) <= d_i(8); d(9) <= d_i(9); d(8) <= d_i(10); d(7) <= d_i(11);
+ d(6) <= d_i(12); d(5) <= d_i(13); d(4) <= d_i(14); d(3) <= d_i(15);
+ d(2) <= d_i(16); d(1) <= d_i(17); d(0) <= d_i(18);
+
+ -- Calculate the resulting crc.
+ c(0) <= d(18) xor d(16) xor d(15) xor d(12) xor
+ d(10) xor d(5) xor d(4) xor d(3) xor
+ d(1) xor d(0);
+ c(1) <= (not d(18)) xor d(17) xor d(15) xor d(13) xor
+ d(12) xor d(11) xor d(10) xor d(6) xor
+ d(3) xor d(2) xor d(0);
+ c(2) <= (not d(18)) xor d(16) xor d(14) xor d(13) xor
+ d(12) xor d(11) xor d(7) xor d(4) xor
+ d(3) xor d(1);
+ c(3) <= (not d(18)) xor d(17) xor d(16) xor d(14) xor
+ d(13) xor d(10) xor d(8) xor d(3) xor
+ d(2) xor d(1);
+ c(4) <= d(18) xor d(17) xor d(15) xor d(14) xor
+ d(11) xor d(9) xor d(4) xor d(3) xor
+ d(2) xor d(0);
+
+ -- Reverse the bit vector indexes to make them the same as in the standard.
+ crc_o(4) <= c(0); crc_o(3) <= c(1); crc_o(2) <= c(2); crc_o(1) <= c(3);
+ crc_o(0) <= c(4);
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioSerial.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/RioPacketBuffer.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioPacketBuffer.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioPacketBuffer.vhd (revision 50)
@@ -0,0 +1,873 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing RapidIO packet buffering functionallity. Two different entities
+-- are implemented, one with transmission window support and one without.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+
+-------------------------------------------------------------------------------
+-- RioPacketBuffer
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioPacketBuffer.
+--
+-- Generic variables
+-- -----------------
+-- SIZE_ADDRESS_WIDTH - The number of frames in powers of two.
+-- CONTENT_ADDRESS_WIDTH - The total number of entries in the memory that can
+-- be used to store packet data.
+-- CONTENT_WIDTH - The width of the data to store as packet content in the memory.
+-- MAX_PACKET_SIZE - The number of entries that must be available for a new
+-- complete full sized packet to be received. This option is present to ensure
+-- that it is always possible to move a packet to the storage without being
+-- surprised that the storage is suddenly empty.
+-------------------------------------------------------------------------------
+entity RioPacketBuffer is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural := 6;
+ CONTENT_ADDRESS_WIDTH : natural := 8;
+ CONTENT_WIDTH : natural := 32;
+ MAX_PACKET_SIZE : natural := 69);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ inboundWriteFrameFull_o : out std_logic;
+ inboundWriteFrame_i : in std_logic;
+ inboundWriteFrameAbort_i : in std_logic;
+ inboundWriteContent_i : in std_logic;
+ inboundWriteContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+ inboundReadFrameEmpty_o : out std_logic;
+ inboundReadFrame_i : in std_logic;
+ inboundReadFrameRestart_i : in std_logic;
+ inboundReadFrameAborted_o : out std_logic;
+ inboundReadFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ inboundReadContentEmpty_o : out std_logic;
+ inboundReadContent_i : in std_logic;
+ inboundReadContentEnd_o : out std_logic;
+ inboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ outboundWriteFrameFull_o : out std_logic;
+ outboundWriteFrame_i : in std_logic;
+ outboundWriteFrameAbort_i : in std_logic;
+ outboundWriteContent_i : in std_logic;
+ outboundWriteContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+ outboundReadFrameEmpty_o : out std_logic;
+ outboundReadFrame_i : in std_logic;
+ outboundReadFrameRestart_i : in std_logic;
+ outboundReadFrameAborted_o : out std_logic;
+ outboundReadFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ outboundReadContentEmpty_o : out std_logic;
+ outboundReadContent_i : in std_logic;
+ outboundReadContentEnd_o : out std_logic;
+ outboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPacketBuffer.
+-------------------------------------------------------------------------------
+architecture RioPacketBufferImpl of RioPacketBuffer is
+
+ component PacketBufferContinous is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Outbound frame buffers.
+ -----------------------------------------------------------------------------
+ OutboundPacketBuffer: PacketBufferContinous
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ port map(
+ clk=>clk,
+ areset_n=>areset_n,
+ writeFrameFull_o=>outboundWriteFrameFull_o,
+ writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i,
+ writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i,
+
+ readFrameEmpty_o=>outboundReadFrameEmpty_o,
+ readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i,
+ readFrameAborted_o=>outboundReadFrameAborted_o,
+ readFrameSize_o=>outboundReadFrameSize_o,
+ readContentEmpty_o=>outboundReadContentEmpty_o,
+ readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o,
+ readContentData_o=>outboundReadContentData_o);
+
+ -----------------------------------------------------------------------------
+ -- Inbound frame buffers.
+ -----------------------------------------------------------------------------
+ InboundPacketBuffer: PacketBufferContinous
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ port map(
+ clk=>clk,
+ areset_n=>areset_n,
+ writeFrameFull_o=>inboundWriteFrameFull_o,
+ writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i,
+ writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i,
+
+ readFrameEmpty_o=>inboundReadFrameEmpty_o,
+ readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i,
+ readFrameAborted_o=>inboundReadFrameAborted_o,
+ readFrameSize_o=>inboundReadFrameSize_o,
+ readContentEmpty_o=>inboundReadContentEmpty_o,
+ readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o,
+ readContentData_o=>inboundReadContentData_o);
+
+end architecture;
+
+
+
+
+-------------------------------------------------------------------------------
+-- RioPacketBufferWindow
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioPacketBufferWindow.
+-------------------------------------------------------------------------------
+entity RioPacketBufferWindow is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural := 6;
+ CONTENT_ADDRESS_WIDTH : natural := 8;
+ CONTENT_WIDTH : natural := 32;
+ MAX_PACKET_SIZE : natural := 69);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ inboundWriteFrameFull_o : out std_logic;
+ inboundWriteFrame_i : in std_logic;
+ inboundWriteFrameAbort_i : in std_logic;
+ inboundWriteContent_i : in std_logic;
+ inboundWriteContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+ inboundReadFrameEmpty_o : out std_logic;
+ inboundReadFrame_i : in std_logic;
+ inboundReadFrameRestart_i : in std_logic;
+ inboundReadFrameAborted_o : out std_logic;
+ inboundReadContentEmpty_o : out std_logic;
+ inboundReadContent_i : in std_logic;
+ inboundReadContentEnd_o : out std_logic;
+ inboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ outboundWriteFrameFull_o : out std_logic;
+ outboundWriteFrame_i : in std_logic;
+ outboundWriteFrameAbort_i : in std_logic;
+ outboundWriteContent_i : in std_logic;
+ outboundWriteContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+ outboundReadFrameEmpty_o : out std_logic;
+ outboundReadFrame_i : in std_logic;
+ outboundReadFrameRestart_i : in std_logic;
+ outboundReadFrameAborted_o : out std_logic;
+ outboundReadWindowEmpty_o : out std_logic;
+ outboundReadWindowReset_i : in std_logic;
+ outboundReadWindowNext_i : in std_logic;
+ outboundReadContentEmpty_o : out std_logic;
+ outboundReadContent_i : in std_logic;
+ outboundReadContentEnd_o : out std_logic;
+ outboundReadContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPacketBufferWindow.
+-------------------------------------------------------------------------------
+architecture RioPacketBufferWindowImpl of RioPacketBufferWindow is
+
+ component PacketBufferContinous is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+ component PacketBufferContinousWindow is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+ end component;
+
+begin
+
+ -----------------------------------------------------------------------------
+ -- Outbound frame buffers.
+ -----------------------------------------------------------------------------
+ OutboundPacketBuffer: PacketBufferContinousWindow
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ port map(
+ clk=>clk,
+ areset_n=>areset_n,
+ writeFrameFull_o=>outboundWriteFrameFull_o,
+ writeFrame_i=>outboundWriteFrame_i, writeFrameAbort_i=>outboundWriteFrameAbort_i,
+ writeContent_i=>outboundWriteContent_i, writeContentData_i=>outboundWriteContentData_i,
+
+ readFrameEmpty_o=>outboundReadFrameEmpty_o,
+ readFrame_i=>outboundReadFrame_i, readFrameRestart_i=>outboundReadFrameRestart_i,
+ readFrameAborted_o=>outboundReadFrameAborted_o,
+ readWindowEmpty_o=>outboundReadWindowEmpty_o,
+ readWindowReset_i=>outboundReadWindowReset_i,
+ readWindowNext_i=>outboundReadWindowNext_i,
+ readContentEmpty_o=>outboundReadContentEmpty_o,
+ readContent_i=>outboundReadContent_i, readContentEnd_o=>outboundReadContentEnd_o,
+ readContentData_o=>outboundReadContentData_o);
+
+ -----------------------------------------------------------------------------
+ -- Inbound frame buffers.
+ -----------------------------------------------------------------------------
+ InboundPacketBuffer: PacketBufferContinous
+ generic map(
+ SIZE_ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH,
+ CONTENT_ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH,
+ CONTENT_WIDTH=>CONTENT_WIDTH,
+ MAX_PACKET_SIZE=>MAX_PACKET_SIZE)
+ port map(
+ clk=>clk,
+ areset_n=>areset_n,
+ writeFrameFull_o=>inboundWriteFrameFull_o,
+ writeFrame_i=>inboundWriteFrame_i, writeFrameAbort_i=>inboundWriteFrameAbort_i,
+ writeContent_i=>inboundWriteContent_i, writeContentData_i=>inboundWriteContentData_i,
+
+ readFrameEmpty_o=>inboundReadFrameEmpty_o,
+ readFrame_i=>inboundReadFrame_i, readFrameRestart_i=>inboundReadFrameRestart_i,
+ readFrameAborted_o=>inboundReadFrameAborted_o,
+ readFrameSize_o=>open,
+ readContentEmpty_o=>inboundReadContentEmpty_o,
+ readContent_i=>inboundReadContent_i, readContentEnd_o=>inboundReadContentEnd_o,
+ readContentData_o=>inboundReadContentData_o);
+
+end architecture;
+
+
+
+
+-------------------------------------------------------------------------------
+-- PacketBufferContinous
+-- This component stores data in chuncks and stores the size of them. The full
+-- memory can be used, except for one word, or a specified (using generic)
+-- maximum number of frames.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for PacketBufferContinous.
+-------------------------------------------------------------------------------
+entity PacketBufferContinous is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+ readFrameSize_o : out std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0);
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for PacketBufferContinous.
+-------------------------------------------------------------------------------
+architecture PacketBufferContinousImpl of PacketBufferContinous is
+
+ component MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component MemorySimpleDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ -- The number of available word positions left in the memory.
+ signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The position to place new frames.
+ signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The position to remove old frames.
+ signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The size of the current frame.
+ signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The start of unread content.
+ signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The current reading position.
+ signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The end of unread content.
+ signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The current writing position.
+ signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- Memory output signal containing the position of a frame.
+ signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+begin
+
+ -----------------------------------------------------------------------------
+ -- Internal signal assignments.
+ -----------------------------------------------------------------------------
+
+ available <= not (memoryEnd_p - memoryStart_p);
+
+ backIndexNext <= backIndex + 1;
+ frontIndexNext <= frontIndex + 1;
+
+ memoryWriteNext_p <= memoryWrite_p + 1;
+ memoryReadNext_p <= memoryRead_p + 1;
+
+ -----------------------------------------------------------------------------
+ -- Writer logic.
+ -----------------------------------------------------------------------------
+
+ writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or
+ (available < MAX_PACKET_SIZE)) else '0';
+
+ Writer: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ backIndex <= (others=>'0');
+
+ memoryEnd_p <= (others=>'0');
+ memoryWrite_p <= (others=>'0');
+ elsif (clk'event and clk = '1') then
+
+ if (writeFrameAbort_i = '1') then
+ memoryWrite_p <= memoryEnd_p;
+ elsif (writeContent_i = '1') then
+ memoryWrite_p <= memoryWriteNext_p;
+ end if;
+
+ if(writeFrame_i = '1') then
+ memoryEnd_p <= memoryWrite_p;
+ backIndex <= backIndexNext;
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Frame cancellation logic.
+ -----------------------------------------------------------------------------
+
+ process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ readFrameAborted_o <= '0';
+ elsif (clk'event and clk = '1') then
+
+ if ((frontIndex = backIndex) and
+ ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then
+ readFrameAborted_o <= '1';
+ elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then
+ readFrameAborted_o <= '0';
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Reader logic.
+ -----------------------------------------------------------------------------
+
+ readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0';
+ readContentEmpty_o <= '1' when ((frontIndex = backIndex) and
+ (memoryWrite_p = memoryRead_p)) else '0';
+ readFrameSize_o <= std_logic_vector(readFrameEnd_p - memoryStart_p);
+
+ Reader: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ frontIndex <= (others=>'0');
+
+ memoryStart_p <= (others=>'0');
+ memoryRead_p <= (others=>'0');
+
+ readContentEnd_o <= '0';
+ elsif (clk'event and clk = '1') then
+
+ -- REMARK: Break apart into registers to avoid priority ladder???
+ if(readFrameRestart_i = '1') then
+ memoryRead_p <= memoryStart_p;
+ elsif(readContent_i = '1') then
+ if(memoryRead_p = readFrameEnd_p) then
+ readContentEnd_o <= '1';
+ else
+ readContentEnd_o <= '0';
+ memoryRead_p <= memoryReadNext_p;
+ end if;
+ elsif(readFrame_i = '1') then
+ memoryStart_p <= readFrameEnd_p;
+ frontIndex <= frontIndexNext;
+ memoryRead_p <= readFrameEnd_p;
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Frame positioning memory signals.
+ -----------------------------------------------------------------------------
+
+ readFrameEnd_p <= unsigned(framePositionReadData);
+
+ -- Memory to keep frame starting/ending positions in.
+ FramePosition: MemorySimpleDualPortAsync
+ generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH)
+ port map(
+ clkA_i=>clk, enableA_i=>writeFrame_i,
+ addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p),
+ addressB_i=>std_logic_vector(frontIndex), dataB_o=>framePositionReadData);
+
+ -----------------------------------------------------------------------------
+ -- Frame content memory signals.
+ -----------------------------------------------------------------------------
+
+ -- Memory to keep frame content in.
+ -- REMARK: Use paritybits here as well to make sure the frame data does not
+ -- become corrupt???
+ FrameContent: MemorySimpleDualPort
+ generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_WIDTH)
+ port map(
+ clkA_i=>clk, enableA_i=>writeContent_i,
+ addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i,
+ clkB_i=>clk, enableB_i=>readContent_i,
+ addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- PacketBufferContinousWindow
+-- This component stores data in chuncks and stores the size of them. The full
+-- memory can be used, except for one word, or a specified (using generic)
+-- maximum number of frames.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for PacketBufferContinousWindow.
+-------------------------------------------------------------------------------
+entity PacketBufferContinousWindow is
+ generic(
+ SIZE_ADDRESS_WIDTH : natural;
+ CONTENT_ADDRESS_WIDTH : natural;
+ CONTENT_WIDTH : natural;
+ MAX_PACKET_SIZE : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ writeFrameFull_o : out std_logic;
+ writeFrame_i : in std_logic;
+ writeFrameAbort_i : in std_logic;
+ writeContent_i : in std_logic;
+ writeContentData_i : in std_logic_vector(CONTENT_WIDTH-1 downto 0);
+
+ readFrameEmpty_o : out std_logic;
+ readFrame_i : in std_logic;
+ readFrameRestart_i : in std_logic;
+ readFrameAborted_o : out std_logic;
+
+ readWindowEmpty_o : out std_logic;
+ readWindowReset_i : in std_logic;
+ readWindowNext_i : in std_logic;
+
+ readContentEmpty_o : out std_logic;
+ readContent_i : in std_logic;
+ readContentEnd_o : out std_logic;
+ readContentData_o : out std_logic_vector(CONTENT_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for PacketBufferContinousWindow.
+-------------------------------------------------------------------------------
+architecture PacketBufferContinousWindowImpl of PacketBufferContinousWindow is
+
+ component MemorySimpleDualPortAsync is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ component MemorySimpleDualPort is
+ generic(
+ ADDRESS_WIDTH : natural := 1;
+ DATA_WIDTH : natural := 1);
+ port(
+ clkA_i : in std_logic;
+ enableA_i : in std_logic;
+ addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ clkB_i : in std_logic;
+ enableB_i : in std_logic;
+ addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ -- The number of available word positions left in the memory.
+ signal available : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ signal backIndex, backIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+ signal frontIndex, frontIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+ signal windowIndex, windowIndexNext : unsigned(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The size of the current frame.
+ signal readFrameEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The start of unread content.
+ signal memoryStart_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The start of unread window content.
+ signal memoryStartWindow_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The current reading position.
+ signal memoryRead_p, memoryReadNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The end of unread content.
+ signal memoryEnd_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ -- The current writing position.
+ signal memoryWrite_p, memoryWriteNext_p : unsigned(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+
+ signal framePositionReadAddress : std_logic_vector(SIZE_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+ signal framePositionReadData : std_logic_vector(CONTENT_ADDRESS_WIDTH-1 downto 0) := (others=>'0');
+begin
+
+ -----------------------------------------------------------------------------
+ -- Internal signal assignments.
+ -----------------------------------------------------------------------------
+
+ available <= not (memoryEnd_p - memoryStart_p);
+
+ backIndexNext <= backIndex + 1;
+ frontIndexNext <= frontIndex + 1;
+ windowIndexNext <= windowIndex + 1;
+
+ memoryWriteNext_p <= memoryWrite_p + 1;
+ memoryReadNext_p <= memoryRead_p + 1;
+
+ -----------------------------------------------------------------------------
+ -- Writer logic.
+ -----------------------------------------------------------------------------
+
+ writeFrameFull_o <= '1' when ((backIndexNext = frontIndex) or
+ (available < MAX_PACKET_SIZE)) else '0';
+
+ Writer: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ backIndex <= (others=>'0');
+
+ memoryEnd_p <= (others=>'0');
+ memoryWrite_p <= (others=>'0');
+ elsif (clk'event and clk = '1') then
+
+ if (writeFrameAbort_i = '1') then
+ memoryWrite_p <= memoryEnd_p;
+ elsif (writeContent_i = '1') then
+ memoryWrite_p <= memoryWriteNext_p;
+ end if;
+
+ if(writeFrame_i = '1') then
+ memoryEnd_p <= memoryWrite_p;
+ backIndex <= backIndexNext;
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Frame cancellation logic.
+ -----------------------------------------------------------------------------
+
+ process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ readFrameAborted_o <= '0';
+ elsif (clk'event and clk = '1') then
+
+ if ((windowIndex = backIndex) and
+ ((writeFrameAbort_i = '1') and (readFrameRestart_i = '0'))) then
+ readFrameAborted_o <= '1';
+ elsif ((writeFrameAbort_i = '0') and (readFrameRestart_i = '1')) then
+ readFrameAborted_o <= '0';
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Reader logic.
+ -----------------------------------------------------------------------------
+
+ readFrameEmpty_o <= '1' when (frontIndex = backIndex) else '0';
+ readWindowEmpty_o <= '1' when (windowIndex = backIndex) else '0';
+ readContentEmpty_o <= '1' when ((windowIndex = backIndex) and
+ (memoryWrite_p = memoryRead_p)) else '0';
+
+ Reader: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ frontIndex <= (others=>'0');
+ windowIndex <= (others=>'0');
+
+ memoryStart_p <= (others=>'0');
+ memoryStartWindow_p <= (others=>'0');
+ memoryRead_p <= (others=>'0');
+
+ readContentEnd_o <= '0';
+ elsif (clk'event and clk = '1') then
+
+ -- REMARK: Break apart into registers to avoid priority ladder???
+ if(readFrameRestart_i = '1') then
+ memoryRead_p <= memoryStartWindow_p;
+ elsif(readContent_i = '1') then
+ if(memoryRead_p = readFrameEnd_p) then
+ readContentEnd_o <= '1';
+ else
+ readContentEnd_o <= '0';
+ memoryRead_p <= memoryReadNext_p;
+ end if;
+ elsif(readFrame_i = '1') then
+ memoryStart_p <= readFrameEnd_p;
+ frontIndex <= frontIndexNext;
+ elsif(readWindowReset_i = '1') then
+ memoryStartWindow_p <= memoryStart_p;
+ windowIndex <= frontIndex;
+ memoryRead_p <= memoryStart_p;
+ elsif(readWindowNext_i = '1') then
+ memoryStartWindow_p <= readFrameEnd_p;
+ windowIndex <= windowIndexNext;
+ memoryRead_p <= readFrameEnd_p;
+ end if;
+
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Frame positioning memory signals.
+ -----------------------------------------------------------------------------
+
+ -- Assign the address from both frontIndex and windowIndex to be able to
+ -- share the memory between the two different types of accesses. This assumes
+ -- that the window is not accessed at the same time as the other signal.
+ framePositionReadAddress <= std_logic_vector(frontIndex) when (readFrame_i = '1') else
+ std_logic_vector(windowIndex);
+ readFrameEnd_p <= unsigned(framePositionReadData);
+
+ -- Memory to keep frame starting/ending positions in.
+ FramePosition: MemorySimpleDualPortAsync
+ generic map(ADDRESS_WIDTH=>SIZE_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_ADDRESS_WIDTH)
+ port map(
+ clkA_i=>clk, enableA_i=>writeFrame_i,
+ addressA_i=>std_logic_vector(backIndex), dataA_i=>std_logic_vector(memoryWrite_p),
+ addressB_i=>framePositionReadAddress, dataB_o=>framePositionReadData);
+
+ -----------------------------------------------------------------------------
+ -- Frame content memory signals.
+ -----------------------------------------------------------------------------
+
+ -- Memory to keep frame content in.
+ -- REMARK: Use paritybits here as well to make sure the frame data does not
+ -- become corrupt???
+ FrameContent: MemorySimpleDualPort
+ generic map(ADDRESS_WIDTH=>CONTENT_ADDRESS_WIDTH, DATA_WIDTH=>CONTENT_WIDTH)
+ port map(
+ clkA_i=>clk, enableA_i=>writeContent_i,
+ addressA_i=>std_logic_vector(memoryWrite_p), dataA_i=>writeContentData_i,
+ clkB_i=>clk, enableB_i=>readContent_i,
+ addressB_i=>std_logic_vector(memoryRead_p), dataB_o=>readContentData_o);
+
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioPacketBuffer.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/RioPcsUart.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioPcsUart.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioPcsUart.vhd (revision 50)
@@ -0,0 +1,641 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- This file contains a PCS (Physical Control Sublayer) that can transfer
+-- RapidIO symbols accross a 2Mbit 8-bit UART transmission channel.
+-- The coding is similar to the coding used by PPP and uses flags (0x7e)
+-- and escape-sequences (0x7d) to encode special characters.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- RioPcsUart
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioPcsUart.
+-------------------------------------------------------------------------------
+entity RioPcsUart is
+ generic(
+ DIVISOR_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ serial_o : out std_logic;
+ serial_i : in std_logic);
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioPcsUart.
+-------------------------------------------------------------------------------
+architecture RioPcsUartImpl of RioPcsUart is
+
+ component RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+ end component;
+
+ component Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+ end component;
+
+ signal uartEmpty : std_logic;
+ signal uartRead : std_logic;
+ signal uartReadData : std_logic_vector(7 downto 0);
+ signal uartFull : std_logic;
+ signal uartWrite : std_logic;
+ signal uartWriteData : std_logic_vector(7 downto 0);
+
+begin
+
+ SymbolConverter: RioSymbolConverter
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ portInitialized_o=>portInitialized_o,
+ outboundSymbolEmpty_i=>outboundSymbolEmpty_i,
+ outboundSymbolRead_o=>outboundSymbolRead_o, outboundSymbol_i=>outboundSymbol_i,
+ inboundSymbolFull_i=>inboundSymbolFull_i,
+ inboundSymbolWrite_o=>inboundSymbolWrite_o, inboundSymbol_o=>inboundSymbol_o,
+ uartEmpty_i=>uartEmpty, uartRead_o=>uartRead, uartData_i=>uartReadData,
+ uartFull_i=>uartFull, uartWrite_o=>uartWrite, uartData_o=>uartWriteData);
+
+ UartInst: Uart
+ generic map(DIVISOR_WIDTH=>DIVISOR_WIDTH, DATA_WIDTH=>8)
+ port map(
+ clk=>clk, areset_n=>areset_n,
+ divisor_i=>divisor_i,
+ serial_i=>serial_i, serial_o=>serial_o,
+ empty_o=>uartEmpty, read_i=>uartRead, data_o=>uartReadData,
+ full_o=>uartFull, write_i=>uartWrite, data_i=>uartWriteData);
+
+end architecture;
+
+
+
+-------------------------------------------------------------------------------
+-- This module encodes and decodes RapidIO symbols for transmission on a 8-bit
+-- UART using HDLC-like framing (see PPP).
+-- When an idle-symbol is received it will be preceeded by an idle link for a
+-- few micro seconds. This idle link time is used to synchronize the receiver
+-- in the link partner that needs to know when a character is starting and not.
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for RioSymbolConverter.
+-------------------------------------------------------------------------------
+entity RioSymbolConverter is
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ portInitialized_o : out std_logic;
+ outboundSymbolEmpty_i : in std_logic;
+ outboundSymbolRead_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ inboundSymbolFull_i : in std_logic;
+ inboundSymbolWrite_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+
+ uartEmpty_i : in std_logic;
+ uartRead_o : out std_logic;
+ uartData_i : in std_logic_vector(7 downto 0);
+ uartFull_i : in std_logic;
+ uartWrite_o : out std_logic;
+ uartData_o : out std_logic_vector(7 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for RioSymbolConverter.
+-------------------------------------------------------------------------------
+architecture RioSymbolConverterImpl of RioSymbolConverter is
+
+ -- Define the flag sequence and the control escape sequence.
+ constant FLAG_SEQUENCE : std_logic_vector(7 downto 0) := x"7e";
+ constant CONTROL_ESCAPE : std_logic_vector(7 downto 0) := x"7d";
+ constant SILENCE_TIME : natural := 4095;
+ constant IDLE_SYMBOL_TIME : natural := 256;
+ constant LINK_LOST_TIME : natural := 4095;
+
+ type TxStateType is (STATE_SILENCE, STATE_IDLE_0, STATE_IDLE_1,
+ STATE_BUSY_1, STATE_BUSY_2, STATE_SEND_FLAG);
+ signal txState : TxStateType;
+ signal txStateCounter : unsigned(1 downto 0);
+ signal outboundSymbolData : std_logic_vector(7 downto 0);
+
+ type RxStateType is (STATE_INIT, STATE_NORMAL);
+ signal rxState : RxStateType;
+ signal rxStateCounter : unsigned(1 downto 0);
+ signal escapeFound : std_logic;
+
+ signal txTimerReset : std_logic;
+ signal txTimerEnable : std_logic;
+ signal txTimerCounter : unsigned(11 downto 0);
+ signal silenceTxTimerDone : std_logic;
+ signal idleTxTimerDone : std_logic;
+
+ signal rxTimerReset : std_logic;
+ signal rxTimerEnable : std_logic;
+ signal rxTimerCounter : unsigned(11 downto 0);
+ signal lostRxTimerDone : std_logic;
+
+ signal uartWrite : std_logic;
+ signal uartRead : std_logic;
+
+begin
+
+ -- Set the port initialized once the receiver enters its normal state.
+ portInitialized_o <= '1' when (rxState = STATE_NORMAL) else '0';
+
+ -----------------------------------------------------------------------------
+ -- Timer functionallity.
+ -----------------------------------------------------------------------------
+
+ silenceTxTimerDone <= '1' when (txTimerCounter = SILENCE_TIME) else '0';
+ idleTxTimerDone <= '1' when (txTimerCounter = IDLE_SYMBOL_TIME) else '0';
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ txTimerCounter <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (txTimerReset = '1') then
+ txTimerCounter <= (others => '0');
+ elsif (txTimerEnable = '1') then
+ txTimerCounter <= txTimerCounter + 1;
+ end if;
+ end if;
+ end process;
+
+ lostRxTimerDone <= '1' when (rxTimerCounter = LINK_LOST_TIME) else '0';
+
+ process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ rxTimerCounter <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ if (rxTimerReset = '1') then
+ rxTimerCounter <= (others => '0');
+ elsif (rxTimerEnable = '1') then
+ rxTimerCounter <= rxTimerCounter + 1;
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Link symbol encoder process.
+ -----------------------------------------------------------------------------
+ outboundSymbolData <= outboundSymbol_i(31 downto 24) when txStateCounter = 0 else
+ outboundSymbol_i(23 downto 16) when txStateCounter = 1 else
+ outboundSymbol_i(15 downto 8) when txStateCounter = 2 else
+ outboundSymbol_i(7 downto 0);
+
+ uartWrite_o <= uartWrite;
+ Outbound: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ txState <= STATE_SILENCE;
+ txStateCounter <= (others => '0');
+
+ txTimerReset <= '0';
+ txTimerEnable <= '0';
+
+ outboundSymbolRead_o <= '0';
+
+ uartWrite <= '0';
+ uartData_o <= (others => '0');
+ elsif (clk'event and clk = '1') then
+ txTimerReset <= '0';
+ outboundSymbolRead_o <= '0';
+ uartWrite <= '0';
+
+ -- Check if the UART is ready for new data.
+ if (uartFull_i = '0') and (uartWrite = '0') then
+ -- The UART want new data to transmitt.
+
+ -- Check the transmission state.
+ case txState is
+
+ when STATE_SILENCE =>
+ -------------------------------------------------------------------
+ -- Wait for a while to let the linkpartner detect a link break.
+ -------------------------------------------------------------------
+ -- Check if the silence timer has expired.
+ if (silenceTxTimerDone = '1') then
+ -- Silence timer expired.
+ -- Reset the timer and proceed to transmitting symbols.
+ txTimerReset <= '1';
+ txTimerEnable <= '0';
+ txState <= STATE_IDLE_0;
+ else
+ txTimerEnable <= '1';
+ end if;
+
+ when STATE_IDLE_0 =>
+ -----------------------------------------------------------------
+ -- Wait for a new symbol to be received. An idle symbol is followed
+ -- by a small inter-character idle time to let the receiver in the
+ -- link partner synchronize itself to the link.
+ -----------------------------------------------------------------
+
+ -- Reset the state counter for the symbol generation.
+ txStateCounter <= "00";
+
+ -- Check if a new symbol is available.
+ if (outboundSymbolEmpty_i = '0') then
+ -- A new symbol is available.
+
+ -- Check if the new symbol is idle, control or data.
+ if (outboundSymbol_i(33 downto 32) /= SYMBOL_IDLE) then
+ -- Control or data symbol.
+ txState <= STATE_BUSY_1;
+ else
+ -- Send idle sequence.
+ txState <= STATE_IDLE_1;
+ end if;
+ else
+ -- No new symbols are ready.
+ -- Dont do anything.
+ end if;
+
+ when STATE_IDLE_1 =>
+ -------------------------------------------------------------------
+ -- Wait until the idle timer has expired to let the link be idle in
+ -- between idle symbols.
+ -------------------------------------------------------------------
+
+ -- Check if the idle timer has expired.
+ if (idleTxTimerDone = '1') then
+ -- Idle timer has expired.
+ -- Reset the timer and disable it.
+ txTimerReset <= '1';
+ txTimerEnable <= '0';
+
+ -- Write a flag to indicate idle link.
+ uartWrite <= '1';
+ uartData_o <= FLAG_SEQUENCE;
+
+ -- Get a new symbol.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ else
+ -- Idle timer has not expired yet.
+ txTimerEnable <= '1';
+ end if;
+
+ when STATE_BUSY_1 =>
+ -----------------------------------------------------------------
+ -- Encode a control or data symbol. If stuffing is needed the next
+ -- busy state is called.
+ -----------------------------------------------------------------
+
+ -- Check if the octet is a flag or escape character.
+ if ((outboundSymbolData = FLAG_SEQUENCE) or
+ (outboundSymbolData = CONTROL_ESCAPE)) then
+ -- Flag or escape octet.
+ uartWrite <= '1';
+ uartData_o <= CONTROL_ESCAPE;
+ txState <= STATE_BUSY_2;
+ else
+ -- Ordinary octet.
+
+ -- Write the octet to the uart.
+ uartWrite <= '1';
+ uartData_o <= outboundSymbolData;
+
+ -- Update to the next octet in the symbol.
+ txStateCounter <= txStateCounter + 1;
+
+ -- Check if the symbol has been sent.
+ if (txStateCounter = 3) then
+ -- Data symbol sent.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ elsif ((txStateCounter = 2) and
+ (outboundSymbol_i(33 downto 32) /= SYMBOL_DATA)) then
+ -- Control symbol sent.
+ txState <= STATE_SEND_FLAG;
+ else
+ -- Symbol not completly sent.
+ txState <= STATE_BUSY_1;
+ end if;
+ end if;
+
+ when STATE_BUSY_2 =>
+ -----------------------------------------------------------------
+ -- Byte stuff a flag or escape sequence found in the symbol data
+ -- content.
+ -----------------------------------------------------------------
+
+ -- Byte stuff the control character.
+ uartWrite <= '1';
+ uartData_o <= outboundSymbolData xor x"20";
+
+ -- Update to the next symbol.
+ txStateCounter <= txStateCounter + 1;
+
+ -- Check if the symbol has been sent.
+ if (txStateCounter = 3) then
+ -- Data symbol sent.
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+ elsif ((txStateCounter = 2) and
+ (outboundSymbol_i(33 downto 32) /= SYMBOL_DATA)) then
+ -- Control symbol sent.
+ txState <= STATE_SEND_FLAG;
+ else
+ -- Symbol not completly sent.
+ txState <= STATE_BUSY_1;
+ end if;
+
+ when STATE_SEND_FLAG =>
+ -----------------------------------------------------------------
+ -- Force a flag to be written to the link.
+ -----------------------------------------------------------------
+
+ uartWrite <= '1';
+ uartData_o <= FLAG_SEQUENCE;
+ outboundSymbolRead_o <= '1';
+ txState <= STATE_IDLE_0;
+
+ when others =>
+ -----------------------------------------------------------------
+ -- Unknown state.
+ -----------------------------------------------------------------
+ txState <= STATE_IDLE_0;
+
+ end case;
+ else
+ -- The UART is busy transmitting.
+ -- Wait for the UART to complete.
+ end if;
+ end if;
+ end process;
+
+
+ -----------------------------------------------------------------------------
+ -- Link symbol decoder process.
+ -----------------------------------------------------------------------------
+ uartRead_o <= uartRead;
+ Inbound: process(areset_n, clk)
+ begin
+ if (areset_n = '0') then
+ rxState <= STATE_INIT;
+ rxStateCounter <= (others => '0');
+ escapeFound <= '0';
+
+ rxTimerReset <= '0';
+ rxTimerEnable <= '0';
+
+ inboundSymbolWrite_o <= '0';
+ inboundSymbol_o <= (others => '0');
+
+ uartRead <= '0';
+ elsif (clk'event and clk = '1') then
+ rxTimerReset <= '0';
+ inboundSymbolWrite_o <= '0';
+ uartRead <= '0';
+
+ case rxState is
+
+ when STATE_INIT =>
+ -------------------------------------------------------------------
+ -- Wait for a flag to be received.
+ -------------------------------------------------------------------
+ -- Check if any new data is ready.
+ if (uartRead = '0') and (uartEmpty_i = '0') then
+ -- New data is ready from the uart.
+
+ -- Check if a flag has been received.
+ if (uartData_i = FLAG_SEQUENCE) then
+ -- A flag has been received.
+ -- Considder the port to be initialized.
+ rxState <= STATE_NORMAL;
+ rxStateCounter <= (others => '0');
+ escapeFound <= '0';
+ rxTimerReset <= '1';
+ rxTimerEnable <= '1';
+ uartRead <= '1';
+ else
+ -- Something that is not a flag has been received.
+ -- Discard the data and wait for a flag.
+ uartRead <= '1';
+ end if;
+ else
+ -- Waiting for inbound data.
+ -- Dont do anything.
+ end if;
+
+ when STATE_NORMAL =>
+ -------------------------------------------------------------------
+ -- Parse the incoming stream and create symbols.
+ -------------------------------------------------------------------
+
+ -- Check if the link lost timer has expired.
+ if (lostRxTimerDone = '1') then
+ -- The link lost timer has expired.
+ -- Reset the timer, disable it and go back to the initial state.
+ rxTimerReset <= '1';
+ rxTimerEnable <= '0';
+ rxState <= STATE_INIT;
+ else
+ -- The link lost timer has not expired.
+
+ -- Check if any new data is ready.
+ if (uartRead = '0') and (uartEmpty_i = '0') then
+ -- New data is ready from the uart.
+
+ -- Reset the link lost timer.
+ rxTimerReset <= '1';
+
+ -- Check if a flag has been received.
+ if (uartData_i /= FLAG_SEQUENCE) then
+ -- The received octet was not a flag.
+
+ -- Check if the octet was a contol character.
+ if (uartData_i /= CONTROL_ESCAPE) then
+ -- The octet was not a control character.
+
+ -- Check where in a symbol the reception is.
+ case rxStateCounter is
+
+ when "00" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ if (escapeFound = '0') then
+ inboundSymbol_o(31 downto 24) <= uartData_i;
+ else
+ inboundSymbol_o(31 downto 24) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "01" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ if (escapeFound = '0') then
+ inboundSymbol_o(23 downto 16) <= uartData_i;
+ else
+ inboundSymbol_o(23 downto 16) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "10" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_CONTROL;
+ if (escapeFound = '0') then
+ inboundSymbol_o(15 downto 8) <= uartData_i;
+ else
+ inboundSymbol_o(15 downto 8) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+
+ when "11" =>
+ inboundSymbol_o(33 downto 32) <= SYMBOL_DATA;
+ if (escapeFound = '0') then
+ inboundSymbol_o(7 downto 0) <= uartData_i;
+ else
+ inboundSymbol_o(7 downto 0) <= uartData_i xor x"20";
+ end if;
+ rxStateCounter <= rxStateCounter + 1;
+ inboundSymbolWrite_o <= '1';
+
+ when others =>
+ rxStateCounter <= "00";
+
+ end case;
+
+ -- Read the octet from the uart.
+ uartRead <= '1';
+ escapeFound <= '0';
+ else
+ -- Control escape received.
+
+ -- Read the octet and indicate that an escape character has been received.
+ uartRead <= '1';
+ escapeFound <= '1';
+ end if;
+ else
+ -- Flag received.
+
+ -- Check if there are any unsent symbols pending.
+ if (rxStateCounter = 0) then
+ -- No pending symbol.
+ -- Send an idle symbol.
+ inboundSymbolWrite_o <= '1';
+ inboundSymbol_o(33 downto 32) <= SYMBOL_IDLE;
+ else
+ -- Pending symbol.
+ -- Send the pending symbol.
+ inboundSymbolWrite_o <= '1';
+ end if;
+
+ -- Read and discard the octet.
+ uartRead <= '1';
+ rxStateCounter <= "00";
+ end if;
+ else
+ -- Waiting for inbound data.
+ -- Dont do anything.
+ end if;
+ end if;
+
+ when others =>
+ -------------------------------------------------------------------
+ -- Unknown state.
+ -------------------------------------------------------------------
+ null;
+
+ end case;
+ end if;
+ end process;
+
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioPcsUart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/Uart.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/Uart.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/Uart.vhd (revision 50)
@@ -0,0 +1,349 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Generic UART with FIFO interface.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Magnus Rosenius, magro732@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Uart implementation.
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+-------------------------------------------------------------------------------
+-- Entity for Uart.
+-------------------------------------------------------------------------------
+entity Uart is
+ generic(
+ DIVISOR_WIDTH : natural;
+ DATA_WIDTH : natural);
+ port(
+ clk : in std_logic;
+ areset_n : in std_logic;
+
+ divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
+
+ serial_i : in std_logic;
+ serial_o : out std_logic;
+
+ empty_o : out std_logic;
+ read_i : in std_logic;
+ data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ full_o : out std_logic;
+ write_i : in std_logic;
+ data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
+end entity;
+
+
+-------------------------------------------------------------------------------
+-- Architecture for Uart.
+-------------------------------------------------------------------------------
+architecture UartImpl of Uart is
+ signal bitDuration : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal bitSample : unsigned(DIVISOR_WIDTH-1 downto 0);
+
+ type StateTypeRx is (STATE_INIT, STATE_IDLE,
+ STATE_START, STATE_DATA, STATE_STOP);
+ signal rxState : StateTypeRx;
+ signal rxShifter : std_logic_vector(DATA_WIDTH-1 downto 0);
+ signal rxCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal rxBitCounter : natural range 0 to DATA_WIDTH-1;
+ signal rxComplete : std_logic;
+ signal rxData : std_logic_vector(DATA_WIDTH-1 downto 0);
+
+ type StateTypeRxFifo is (STATE_EMPTY, STATE_WAITREAD);
+ signal rxFifoState : StateTypeRxFifo;
+
+ type StateTypeTx is (STATE_IDLE, STATE_SEND);
+ signal txState : StateTypeTx;
+ signal txShifter : std_logic_vector(DATA_WIDTH downto 0);
+ signal txCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
+ signal txBitCounter : natural range 0 to DATA_WIDTH+1;
+
+begin
+
+ -- Setup the tick values when a bit is complete and when to sample it.
+ bitDuration <= unsigned(divisor_i);
+ bitSample <= '0' & unsigned(divisor_i(DIVISOR_WIDTH-1 downto 1));
+
+ -----------------------------------------------------------------------------
+ -- UART receiving process.
+ -----------------------------------------------------------------------------
+ Receiver: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ rxState <= STATE_INIT;
+ rxShifter <= (others => '0');
+ rxBitCounter <= 0;
+ rxCounter <= (others => '0');
+
+ rxComplete <= '0';
+ rxData <= (others => '0');
+ elsif (clk'event and (clk = '1')) then
+ rxComplete <= '0';
+
+ case rxState is
+
+ when STATE_INIT =>
+ ---------------------------------------------------------------------
+ -- Wait for the line to become idle.
+ ---------------------------------------------------------------------
+ if (serial_i = '1') then
+ rxState <= STATE_IDLE;
+ end if;
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for a long enough start pulse.
+ ---------------------------------------------------------------------
+ if (serial_i = '0') then
+ -- The serial input is zero, indicating a start bit.
+
+ -- Check how long it has been zero.
+ if (rxCounter = bitSample) then
+ -- It has been zero long enough.
+ -- Proceed to read the full start bit before starting to sample
+ -- the data.
+ rxState <= STATE_START;
+ else
+ -- Stay in this state until it has lasted long enough.
+ end if;
+
+ -- Update to next sampling interval.
+ rxCounter <= rxCounter + 1;
+ else
+ -- The serial input is not zero.
+ -- Restart the sampling interval.
+ rxCounter <= (others => '0');
+ end if;
+
+ when STATE_START =>
+ ---------------------------------------------------------------------
+ -- Wait for the startbit to end.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitDuration) then
+ rxCounter <= (others => '0');
+ rxState <= STATE_DATA;
+ else
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when STATE_DATA =>
+ ---------------------------------------------------------------------
+ -- Sample data bits where it's appropriate.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitDuration) then
+ -- End of bit.
+ -- Check if all the data bits has been read.
+ if (rxBitCounter = (DATA_WIDTH-1)) then
+ -- All data bits read.
+ -- Read the stop bit.
+ rxState <= STATE_STOP;
+ rxBitCounter <= 0;
+ else
+ -- Continue to read more data bits.
+ rxBitCounter <= rxBitCounter + 1;
+ end if;
+
+ -- Restart sampling interval.
+ rxCounter <= (others => '0');
+ elsif (rxCounter = bitSample) then
+ -- Sample the bit and continue to sample until the bit ends.
+ rxShifter <= serial_i & rxShifter((DATA_WIDTH-1) downto 1);
+ rxCounter <= rxCounter + 1;
+ else
+ -- Wait for the middle or the end of the data to be reached.
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when STATE_STOP =>
+ ---------------------------------------------------------------------
+ -- Sample stop bit where it's appropriate.
+ ---------------------------------------------------------------------
+ if (rxCounter = bitSample) then
+ -- Sample the stop bit.
+
+ -- Check if the stop bit is valid.
+ if (serial_i = '1') then
+ -- The stop bit is ok.
+ -- Forward the read data.
+ rxComplete <= '1';
+ rxData <= rxShifter;
+ else
+ -- The stop bit is not ok.
+ -- Do not forward the data character.
+ end if;
+
+ -- Reset sampling counter and go back to the init state.
+ rxState <= STATE_INIT;
+ rxCounter <= (others => '0');
+ else
+ -- Wait for the middle or the end of the data to be reached.
+ rxCounter <= rxCounter + 1;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ -- Undefined state.
+ ---------------------------------------------------------------------
+ rxState <= STATE_IDLE;
+ rxCounter <= (others => '0');
+
+ end case;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- UART receiver fifo.
+ -----------------------------------------------------------------------------
+ ReceiverFifo: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ empty_o <= '1';
+ data_o <= (others => '0');
+ rxFifoState <= STATE_EMPTY;
+ elsif (clk'event and (clk = '1')) then
+ case rxFifoState is
+
+ when STATE_EMPTY =>
+ -- Wait for data to be forwarded from the UART receiver.
+ if (rxComplete = '1') then
+ -- Indicate there is data to read from.
+ empty_o <= '0';
+ data_o <= rxData;
+ rxFifoState <= STATE_WAITREAD;
+ else
+ -- Wait for data to be received.
+ end if;
+
+ when STATE_WAITREAD =>
+ -- Wait for the data to be read from the output port.
+ if (read_i = '1') then
+ -- The data has been read.
+ empty_o <= '1';
+ rxFifoState <= STATE_EMPTY;
+ end if;
+ -- Check if new data has been forwarded from the UART.
+ if (rxComplete = '1') then
+ -- New data has been forwarded without the output port being read.
+ -- Overrun. Data has been lost.
+ -- REMARK: Indicate this???
+ end if;
+
+ when others =>
+ -- Undefined state.
+ rxFifoState <= STATE_EMPTY;
+ end case;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- UART transmitter process.
+ -----------------------------------------------------------------------------
+ Transmitter: process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ txState <= STATE_IDLE;
+ txShifter <= (others => '0');
+ txBitCounter <= 0;
+ txCounter <= (others => '0');
+
+ full_o <= '0';
+ serial_o <= '1';
+ elsif (clk'event and (clk = '1')) then
+ case txState is
+
+ when STATE_IDLE =>
+ ---------------------------------------------------------------------
+ -- Wait for new data to be input on the input port.
+ ---------------------------------------------------------------------
+ if (write_i = '1') then
+ -- New data present.
+ full_o <= '1';
+ txShifter <= "1" & data_i;
+ txCounter <= (others => '0');
+ txBitCounter <= 0;
+ txState <= STATE_SEND;
+ serial_o <= '0';
+ end if;
+
+ when STATE_SEND =>
+ ---------------------------------------------------------------------
+ -- Wait for the bit to be completly transmitted.
+ ---------------------------------------------------------------------
+ if (txCounter = bitDuration) then
+ -- The bit has been sent.
+
+ -- Check if the full character has been sent.
+ if (txBitCounter = (DATA_WIDTH+1)) then
+ -- Character has been sent.
+ full_o <= '0';
+ txState <= STATE_IDLE;
+ else
+ -- Character has not been sent yet.
+ -- Send the next bit.
+ serial_o <= txShifter(0);
+ txShifter <= "0" & txShifter(DATA_WIDTH downto 1);
+ txBitCounter <= txBitCounter + 1;
+ end if;
+
+ -- Update to the next bit.
+ txCounter <= (others => '0');
+ else
+ -- Wait for the end of the bit.
+ txCounter <= txCounter + 1;
+ end if;
+
+ when others =>
+ ---------------------------------------------------------------------
+ -- Undefined state.
+ ---------------------------------------------------------------------
+ txState <= STATE_IDLE;
+
+ end case;
+ end if;
+ end process;
+
+end architecture;
+
tags/1.0.2-release/rtl/vhdl/Uart.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/rtl/vhdl/srio_pcs_struct.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/srio_pcs_struct.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/srio_pcs_struct.vhd (revision 50)
@@ -0,0 +1,2912 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: ccs_timer.vhd
+-- Rev: 0.0
+-- Description: This entity watches the CCS (clock compensation sequence)
+-- insertion according to RIO Sepec. Part-6, subchapter 4.7.1
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+entity ccs_timer is
+ generic (
+ TCQ : time := 100 ps
+ );
+ port (
+ rst_n : in std_logic;
+ UCLK : in std_logic;
+
+ send_ccs : out std_logic;
+ ccs_timer_rst : in std_logic
+ );
+end ccs_timer;
+
+architecture RTL of ccs_timer is
+--------------------------------------------------------------------------------------
+signal ccs_counter : std_logic_vector(11 downto 0) := (others => '0');
+constant CCS_INTERVAL : std_logic_vector(11 downto 0) := x"7FF"; -- = 4096 chars
+
+--------------------------------------------------------------------------------------
+begin
+
+-- CCS counter process
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+ ccs_counter <= CCS_INTERVAL;
+ send_ccs <= '0';
+ elsif rising_edge(UCLK) then
+ if ccs_timer_rst = '0' then
+ if ccs_counter = CCS_INTERVAL then
+ send_ccs <= '1';
+ else
+ send_ccs <= '0';
+ ccs_counter <= ccs_counter + '1';
+ end if;
+ else
+ send_ccs <= '0';
+ ccs_counter <= (others => '0');
+ end if;
+ end if;
+end process;
+
+end RTL;
+---------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: idle_generator.vhd
+-- Rev: 0.0
+-- Description: This entity generates IDLE1 sequence for SRIO PHY
+-- RIO Sepec. Part-6, subchapter 4.7.2
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+entity idle_generator is
+ generic (
+ lfsr_init : std_logic_vector(7 downto 0) := x"01";
+ TCQ : time := 100 ps
+ );
+ port (
+ UCLK : in std_logic;
+ rst_n : in std_logic;
+
+ send_idle : in std_logic;
+
+ send_K : out std_logic;
+ send_A : out std_logic;
+ send_R : out std_logic
+ );
+end idle_generator;
+
+architecture RTL of idle_generator is
+-------------------------------------------------------------------------------------------------------------------------------------------
+signal q_pseudo_random_number : std_logic_vector(7 downto 0) := (others => '0');
+signal pseudo_random_bit : std_logic := '0';
+
+signal down_counter_load_value : std_logic_vector(4 downto 0) := (others => '0');
+signal down_counter : std_logic_vector(4 downto 0) := (others => '0');
+signal Acntr_eq_zero : std_logic := '0';
+signal send_idle_q : std_logic := '0';
+--
+
+COMPONENT pseudo_random_number_generator
+GENERIC (
+ lfsr_init : std_logic_vector(7 downto 0)
+ );
+PORT(
+ clk : IN std_logic;
+ rst_n : IN std_logic;
+ q : OUT std_logic_vector(7 downto 0)
+ );
+END COMPONENT;
+
+-------------------------------------------------------------------------------------------------------------------------------------------
+begin
+
+inst_prng: pseudo_random_number_generator GENERIC MAP(
+ lfsr_init => lfsr_init --x"01"
+ )
+ PORT MAP(
+ clk => UCLK,
+ rst_n => rst_n,
+ q => q_pseudo_random_number
+ );
+
+pseudo_random_bit <= q_pseudo_random_number(0);
+
+down_counter_load_value <= '1' & q_pseudo_random_number(6) & q_pseudo_random_number(4) & q_pseudo_random_number(3) & q_pseudo_random_number(1);
+
+-- down counter process
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+ down_counter <= (others => '0');
+ elsif rising_edge(UCLK) then
+ if Acntr_eq_zero = '1' then
+ down_counter <= down_counter_load_value;
+ else
+ down_counter <= down_counter - '1';
+ end if;
+ end if;
+end process;
+
+Acntr_eq_zero <= '1' when down_counter = "00000" else '0';
+
+-- send_idle delay process
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+ send_idle_q <= '0';
+ elsif rising_edge(UCLK) then
+ send_idle_q <= send_idle;
+ end if;
+end process;
+
+send_K <= send_idle and (not(send_idle_q) or (send_idle_q and not(Acntr_eq_zero) and pseudo_random_bit));
+send_A <= send_idle and send_idle_q and Acntr_eq_zero;
+send_R <= send_idle and send_idle_q and not(Acntr_eq_zero) and not(pseudo_random_bit);
+
+end RTL;
+-------------------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: idle_generator_dual.vhd
+-- Rev: 0.0
+-- Description: This entity generates IDLE1 sequence for SRIO PHY
+-- RIO Sepec. Part-6, subchapter 4.7.2
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+entity idle_generator_dual is
+ generic (
+ TCQ : time := 100 ps
+ );
+ port (
+ UCLK : in std_logic;
+ rst_n : in std_logic;
+
+ send_idle : in std_logic_vector(1 downto 0);
+
+ send_K : out std_logic_vector(1 downto 0);
+ send_A : out std_logic_vector(1 downto 0);
+ send_R : out std_logic_vector(1 downto 0)
+ );
+end idle_generator_dual;
+
+architecture RTL of idle_generator_dual is
+-------------------------------------------------------------------------------------------------------------------------------------------
+
+COMPONENT idle_generator
+ generic (
+ lfsr_init : std_logic_vector(7 downto 0);
+ TCQ : time
+ );
+PORT(
+ UCLK : IN std_logic;
+ rst_n : IN std_logic;
+ send_idle : IN std_logic;
+ send_K : OUT std_logic;
+ send_A : OUT std_logic;
+ send_R : OUT std_logic
+ );
+END COMPONENT;
+
+-------------------------------------------------------------------------------------------------------------------------------------------
+begin
+
+ Inst_idle_generator_0: idle_generator GENERIC MAP(
+ TCQ => 100 ps,
+ lfsr_init => x"0F"
+ )
+ PORT MAP(
+ UCLK => UCLK,
+ rst_n => rst_n,
+ send_idle => send_idle(0),
+ send_K => send_K(0),
+ send_A => send_A(0),
+ send_R => send_R(0)
+ );
+
+ Inst_idle_generator_1: idle_generator GENERIC MAP(
+ TCQ => 100 ps,
+ lfsr_init => x"F0"
+ )
+ PORT MAP(
+ UCLK => UCLK,
+ rst_n => rst_n,
+ send_idle => send_idle(1),
+ send_K => send_K(1),
+ send_A => send_A(1),
+ send_R => send_R(1)
+ );
+
+end RTL;
+-------------------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: pcs_rx_controller.vhd
+-- Rev: 0.0
+-- Description: This entity controls the RX stream
+--
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+entity pcs_rx_controller is
+ generic (
+ TCQ : time := 100 ps
+ );
+ port (
+ rst_n : in std_logic;
+ rio_clk : in std_logic; -- ~150 MHz
+ UCLK_x2 : in std_logic; -- 312,5 MHz
+ UCLK : in std_logic; -- 156,25 MHz
+ UCLK_x2_DV2 : in std_logic; -- 312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode)
+ UCLK_or_DV4 : in std_logic; -- 156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode)
+ -- UCLK_DV4 : in std_logic; -- 39,0625
+ --
+ -- Interface to the RioSerial
+ inboundRead_i : in std_logic;
+ inboundEmpty_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector(33 downto 0);
+ --
+ -- Interface to the GTX transceivers
+ RXDATA_i : in std_logic_vector(63 downto 0); -- N = 4
+ RXCHARISK_i : in std_logic_vector(7 downto 0);
+ RXCHARISvalid_i : in std_logic_vector(7 downto 0);
+ --
+ -- Interface to the port init
+ port_initalized_i : in std_logic;
+ mode_sel_i : in std_logic;
+ mode_0_lane_sel_i : in std_logic
+
+ );
+end pcs_rx_controller;
+
+architecture RTL of pcs_rx_controller is
+
+-------------------------------------------------------------------------------
+COMPONENT pcs_rx_boudary_32b_out_64b_in
+ PORT (
+ rst : IN STD_LOGIC;
+ wr_clk : IN STD_LOGIC;
+ rd_clk : IN STD_LOGIC;
+ din : IN STD_LOGIC_VECTOR(67 DOWNTO 0);
+ wr_en : IN STD_LOGIC;
+ rd_en : IN STD_LOGIC;
+ dout : OUT STD_LOGIC_VECTOR(33 DOWNTO 0);
+ full : OUT STD_LOGIC;
+ almost_full : OUT STD_LOGIC;
+ empty : OUT STD_LOGIC;
+ almost_empty : OUT STD_LOGIC;
+ valid : OUT STD_LOGIC
+ );
+END COMPONENT;
+-------------------------------------------------------------------------------
+signal rst : std_logic:= '0';
+
+signal RXDATA_swap : std_logic_vector(63 downto 0) := (others => '0');
+signal RXCHARISK_swap : std_logic_vector(7 downto 0) := (others => '0');
+signal RXCHARISvalid_swap : std_logic_vector(7 downto 0) := (others => '0');
+
+signal RXDATA_u : std_logic_vector(31 downto 0) := (others => '0');
+signal RXCHARISK_u : std_logic_vector(3 downto 0) := (others => '0');
+signal RXDATA_l : std_logic_vector(31 downto 0) := (others => '0');
+signal RXCHARISK_l : std_logic_vector(3 downto 0) := (others => '0');
+signal RXCHARISvalid_u : std_logic_vector(3 downto 0) := (others => '0');
+signal RXCHARISvalid_l : std_logic_vector(3 downto 0) := (others => '0');
+
+signal inboundValid : std_logic:= '0';
+signal rx_fifo_wr_en : std_logic:= '0';
+signal rx_fifo_wr_en_q : std_logic:= '0';
+signal rx_fifo_full : std_logic:= '0';
+signal rx_fifo_almost_full : std_logic:= '0';
+signal rx_fifo_almost_empty : std_logic:= '0';
+
+signal rx_fifo_data_in : std_logic_vector(67 downto 0) := (others => '0');
+signal rx_fifo_data_in_q : std_logic_vector(67 downto 0) := (others => '0');
+signal rx_fifo_data_swapped : std_logic_vector(67 downto 0) := (others => '0');
+signal rx_fifo_full_p : std_logic:= '0';
+
+signal port_initalized : std_logic:= '0';
+signal mode_sel : std_logic:= '0';
+signal mode_0_lane_sel : std_logic:= '0';
+
+signal port_state : std_logic_vector(2 downto 0) := (others => '0');
+
+signal upper_symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+signal lower_symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+
+signal upper_symbol_not_idle : std_logic:= '0';
+signal lower_symbol_not_idle : std_logic:= '0';
+signal upper_symbol_valid : std_logic:= '0';
+signal lower_symbol_valid : std_logic:= '0';
+signal upper_symbol_not_error : std_logic:= '0';
+signal lower_symbol_not_error : std_logic:= '0';
+
+-- signal RXDATA_sr : std_logic_vector(63 downto 0) := (others => '0');
+-- signal RXCHARISK_sr : std_logic_vector(7 downto 0) := (others => '0');
+-- signal RXCHARISvalid_sr : std_logic_vector(7 downto 0) := (others => '0');
+
+signal RXDATA_sr_done : std_logic_vector(63 downto 0) := (others => '0');
+signal RXCHARISK_sr_done : std_logic_vector(7 downto 0) := (others => '0');
+signal RXCHARISvalid_sr_done : std_logic_vector(7 downto 0) := (others => '0');
+
+signal RXDATA_sr : std_logic_vector(71 downto 0) := (others => '0');
+signal RXCHARISK_sr : std_logic_vector(8 downto 0) := (others => '0');
+signal RXCHARISvalid_sr : std_logic_vector(8 downto 0) := (others => '0');
+
+signal RXDATA_R_lane : std_logic_vector(15 downto 0) := (others => '0');
+signal RXCHARISK_R_lane : std_logic_vector(1 downto 0) := (others => '0');
+signal RXCHARISvalid_R_lane : std_logic_vector(1 downto 0) := (others => '0');
+
+signal valid_byte_cntr : std_logic_vector(2 downto 0) := (others => '0');
+signal irregular_stream : std_logic:= '0';
+signal done_cntr : std_logic_vector(1 downto 0) := (others => '0');
+signal rx_done : std_logic:= '0';
+
+signal u_l_switch : std_logic:= '0';
+
+-- signal sr_symbol_not_idle : std_logic:= '0';
+-- signal sr_symbol_not_idle_q : std_logic:= '0';
+-- signal sr_symbol_not_error : std_logic:= '0';
+-- signal sr_symbol_not_error_q : std_logic:= '0';
+-- signal RXDATA_sr : std_logic_vector(31 downto 0) := (others => '0');
+-- signal RXCHARISK_sr : std_logic_vector(3 downto 0) := (others => '0');
+-- signal RXCHARISvalid_sr : std_logic_vector(3 downto 0) := (others => '0');
+-- signal sr_symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+
+signal sr_u_symbol_not_idle : std_logic:= '0';
+signal sr_u_symbol_not_idle_q : std_logic:= '0';
+signal sr_u_symbol_not_error : std_logic:= '0';
+signal sr_u_symbol_not_error_q : std_logic:= '0';
+signal RXDATA_u_sr : std_logic_vector(31 downto 0) := (others => '0');
+signal RXCHARISK_u_sr : std_logic_vector(3 downto 0) := (others => '0');
+signal RXCHARISvalid_u_sr : std_logic_vector(3 downto 0) := (others => '0');
+signal sr_u_symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+
+signal sr_l_symbol_not_idle : std_logic:= '0';
+signal sr_l_symbol_not_idle_q : std_logic:= '0';
+signal sr_l_symbol_not_error : std_logic:= '0';
+signal sr_l_symbol_not_error_q : std_logic:= '0';
+signal RXDATA_sr_l : std_logic_vector(31 downto 0) := (others => '0');
+signal RXCHARISK_sr_l : std_logic_vector(3 downto 0) := (others => '0');
+signal RXCHARISvalid_sr_l : std_logic_vector(3 downto 0) := (others => '0');
+signal sr_l_symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+
+
+signal started_once : std_logic:= '0';
+signal word_switch : std_logic:= '0';
+signal shift_cntr : std_logic_vector(1 downto 0) := (others => '0');
+
+
+----------------------------------------------------------------------------------
+begin
+rst <= not(rst_n);
+
+rx_boundary_fifo : pcs_rx_boudary_32b_out_64b_in -- FWFT FIFO
+ PORT MAP (
+ rst => rst,
+ rd_clk => rio_clk,
+ rd_en => inboundRead_i,
+ dout => inboundSymbol_o,
+ valid => inboundValid,
+ empty => inboundEmpty_o,
+ almost_empty => rx_fifo_almost_empty,
+
+ wr_clk => UCLK_or_DV4,
+ wr_en => rx_fifo_wr_en_q, -- rx_fifo_wr_en, -- rx_fifo_wr_en_q, --
+ din => rx_fifo_data_in_q, -- rx_fifo_data_in, -- rx_fifo_data_in_q, --
+ full => rx_fifo_full, -- rx_fifo_full
+ almost_full => rx_fifo_almost_full -- rx_fifo_full
+ );
+
+-- Pipelining RX write
+process(UCLK_or_DV4)
+ begin
+ if rising_edge(UCLK_or_DV4) then
+ rx_fifo_wr_en_q <= rx_fifo_wr_en;
+ rx_fifo_data_in_q <= rx_fifo_data_in;
+ end if;
+end process;
+
+
+-- rx_fifo_data_swapped <= rx_fifo_data_in(33 downto 32)
+-- & rx_fifo_data_in(7 downto 0) & rx_fifo_data_in(15 downto 8) & rx_fifo_data_in(23 downto 16) & rx_fifo_data_in(31 downto 24);
+
+port_initalized <= port_initalized_i;
+mode_sel <= mode_sel_i;
+mode_0_lane_sel <= mode_0_lane_sel_i;
+
+port_state <= port_initalized & mode_sel & mode_0_lane_sel;
+
+-- RX management / FIFO write process
+process(rst_n, UCLK) -- _x2
+ begin
+ if rst_n = '0' then
+
+ rx_fifo_wr_en <= '0';
+ word_switch <= '0';
+ started_once <= '0';
+ rx_fifo_data_in <= (others => '0');
+ -- RXDATA_sr <= (others => '0');
+ -- RXCHARISK_sr <= (others => '1');
+ -- RXCHARISvalid_sr <= (others => '0');
+ shift_cntr <= (others => '0');
+
+ elsif rising_edge(UCLK) then
+ -- Alternative If-Else Statement
+ if port_initalized = '0' then -- Port has not been initialized yet
+ rx_fifo_wr_en <= '0';
+ rx_fifo_data_in <= (others => '0');
+ else -- Port has been initialized
+ -- if mode_sel = '1' then -- x4 mode is active
+ if upper_symbol_valid = '1' and lower_symbol_valid = '1' then
+ rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l;
+ rx_fifo_wr_en <= not(rx_fifo_almost_full);
+ elsif upper_symbol_valid = '1' then
+ rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & x"00000000";
+ rx_fifo_wr_en <= not(rx_fifo_almost_full);
+ elsif lower_symbol_valid = '1' then
+ rx_fifo_data_in <= SYMBOL_IDLE & x"00000000" & lower_symbol_type & RXDATA_l;
+ rx_fifo_wr_en <= not(rx_fifo_almost_full);
+ else
+ rx_fifo_wr_en <= '0';
+ end if;
+ -- else -- x1 fallback mode is active
+ -- if upper_symbol_valid = '1' and lower_symbol_valid = '1' then
+ -- rx_fifo_data_in <= upper_symbol_type & RXDATA_u & lower_symbol_type & RXDATA_l;
+ -- rx_fifo_wr_en <= not(rx_fifo_full);
+ -- elsif upper_symbol_valid = '1' then
+ -- rx_fifo_data_in <= upper_symbol_type & RXDATA_u & SYMBOL_IDLE & RXDATA_l;
+ -- rx_fifo_wr_en <= not(rx_fifo_full);
+ -- elsif lower_symbol_valid = '1' then
+ -- rx_fifo_data_in <= SYMBOL_IDLE & RXDATA_u & lower_symbol_type & RXDATA_l;
+ -- rx_fifo_wr_en <= not(rx_fifo_full);
+ -- else
+ -- rx_fifo_wr_en <= '0';
+ -- end if;
+ -- end if;
+ end if;
+ end if;
+end process;
+-------------------------------------------------------------------------------------------------------------------------------------------------------
+
+-- -- Pipelining RX stream
+-- process(UCLK)
+-- begin
+-- if rising_edge(UCLK) then
+-- RXDATA_swap <= RXDATA_i(15 downto 0) & RXDATA_i(31 downto 16) & RXDATA_i(47 downto 32) & RXDATA_i(63 downto 48);
+-- RXCHARISK_swap <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6);
+-- RXCHARISvalid_swap <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6);
+-- end if;
+-- end process;
+
+-- Pipelining RX stream
+process(UCLK)
+ begin
+ if rising_edge(UCLK) then
+
+ RXDATA_swap <= RXDATA_i(15 downto 0) & RXDATA_i(31 downto 16) & RXDATA_i(47 downto 32) & RXDATA_i(63 downto 48);
+ RXCHARISK_swap <= RXCHARISK_i(1 downto 0) & RXCHARISK_i(3 downto 2) & RXCHARISK_i(5 downto 4) & RXCHARISK_i(7 downto 6);
+ RXCHARISvalid_swap <= RXCHARISvalid_i(1 downto 0) & RXCHARISvalid_i(3 downto 2) & RXCHARISvalid_i(5 downto 4) & RXCHARISvalid_i(7 downto 6);
+
+ -- if mode_sel = '1' then -- x4 mode is active
+
+ -- else -- x1 fallback mode is active
+ --
+ -- RXDATA_swap <= RXDATA_sr_done ;
+ -- RXCHARISK_swap <= RXCHARISK_sr_done ;
+ -- RXCHARISvalid_swap <= RXCHARISvalid_sr_done ;
+ --
+ -- end if;
+ end if;
+end process;
+--- Lane 0 active Lane 2 active
+RXDATA_R_lane <= RXDATA_i(15 downto 0) when mode_0_lane_sel = '0' else RXDATA_i(47 downto 32) ;
+RXCHARISK_R_lane <= RXCHARISK_i(1 downto 0) when mode_0_lane_sel = '0' else RXCHARISK_i(5 downto 4) ;
+RXCHARISvalid_R_lane <= RXCHARISvalid_i(1 downto 0) when mode_0_lane_sel = '0' else RXCHARISvalid_i(5 downto 4) ;
+
+-- RXDATA shifting process for x1 mode
+process(UCLK) -- _x2 rst_n,
+ begin
+ -- if rst_n = '0' then
+ --
+ -- RXDATA_sr <= (others => '0');
+ -- RXCHARISK_sr <= (others => '1');
+ -- RXCHARISvalid_sr <= (others => '0');
+ -- valid_byte_cntr <= (others => '0');
+ --
+ -- RXDATA_sr_done <= (others => '0');
+ -- RXCHARISK_sr_done <= (others => '1');
+ -- RXCHARISvalid_sr_done <= (others => '0');
+ --
+ -- done_cntr <= (others => '0');
+ -- rx_done <= '0';
+ --
+ -- els
+ if rising_edge(UCLK) then
+
+ if port_initalized = '0' then -- Port has not been initialized yet
+
+ RXDATA_sr <= (others => '0');
+ RXCHARISK_sr <= (others => '1');
+ RXCHARISvalid_sr <= (others => '0');
+ valid_byte_cntr <= (others => '0');
+
+ RXDATA_sr_done <= (others => '0');
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+
+ done_cntr <= (others => '0');
+ rx_done <= '0';
+
+ else
+ done_cntr <= done_cntr + rx_done;
+ if RXCHARISvalid_R_lane(0) = '1' and (RXCHARISK_R_lane(0) = '0' or (RXCHARISK_R_lane(0) = '1' and (RXDATA_R_lane(7 downto 0) = SC or RXDATA_R_lane(7 downto 0) = PD))) then
+ if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then
+ --- [VVVV] It may appear anytime
+ valid_byte_cntr <= valid_byte_cntr + "10";
+ RXDATA_sr <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 0);
+ RXCHARISK_sr <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1 downto 0);
+ RXCHARISvalid_sr <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1 downto 0);
+ if valid_byte_cntr = "110" then
+ irregular_stream <= '0';
+ rx_done <= '1';
+ done_cntr <= (others => '0');
+ RXDATA_sr_done <= RXDATA_sr(47 downto 0) & RXDATA_R_lane(15 downto 0);
+ RXCHARISK_sr_done <= RXCHARISK_sr(5 downto 0) & RXCHARISK_R_lane(1 downto 0);
+ RXCHARISvalid_sr_done <= RXCHARISvalid_sr(5 downto 0) & RXCHARISvalid_R_lane(1 downto 0);
+ elsif valid_byte_cntr = "111" then
+ irregular_stream <= '1';
+ rx_done <= '1';
+ done_cntr <= (others => '0');
+ RXDATA_sr_done <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 8);
+ RXCHARISK_sr_done <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1);
+ RXCHARISvalid_sr_done <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1);
+ elsif done_cntr = "11" then
+ rx_done <= '0';
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+ end if;
+ else
+ --- [__VV] : It can appear only in the beginning
+ if valid_byte_cntr = "100" then
+ valid_byte_cntr <= valid_byte_cntr + '1';
+ else -- either it is an irregular start or something went wrong
+ valid_byte_cntr <= "001";
+ irregular_stream <= '1';
+ end if;
+ RXDATA_sr <= RXDATA_sr(63 downto 0) & RXDATA_R_lane(7 downto 0);
+ RXCHARISK_sr <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(0);
+ RXCHARISvalid_sr <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(0);
+ if done_cntr = "11" then
+ rx_done <= '0';
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+ end if;
+ end if;
+ else
+ if RXCHARISvalid_R_lane(1) = '1' and (RXCHARISK_R_lane(1) = '0' or (RXCHARISK_R_lane(1) = '1' and (RXDATA_R_lane(15 downto 8) = SC or RXDATA_R_lane(15 downto 8) = PD))) then
+ --- [VV__] : It can appear only in the end
+ RXDATA_sr <= RXDATA_sr(63 downto 0) & RXDATA_R_lane(15 downto 8);
+ RXCHARISK_sr <= RXCHARISK_sr(7 downto 0) & RXCHARISK_R_lane(1);
+ RXCHARISvalid_sr <= RXCHARISvalid_sr(7 downto 0) & RXCHARISvalid_R_lane(1);
+ if valid_byte_cntr = "011" then
+ valid_byte_cntr <= valid_byte_cntr + '1';
+ irregular_stream <= '0'; -- irregularity has been compensated for the first symbol
+ if done_cntr = "11" then
+ rx_done <= '0';
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+ end if;
+ elsif valid_byte_cntr = "111" then -- 2 symbols (2x32b) are done
+ valid_byte_cntr <= (others => '0');
+ irregular_stream <= '0'; -- irregularity has been compensated for the second symbol
+ rx_done <= '1';
+ done_cntr <= (others => '0');
+ RXDATA_sr_done <= RXDATA_sr(55 downto 0) & RXDATA_R_lane(15 downto 8);
+ RXCHARISK_sr_done <= RXCHARISK_sr(6 downto 0) & RXCHARISK_R_lane(1);
+ RXCHARISvalid_sr_done <= RXCHARISvalid_sr(6 downto 0) & RXCHARISvalid_R_lane(1);
+ else -- something went wrong
+ valid_byte_cntr <= (others => '0');
+ irregular_stream <= '0';
+ if done_cntr = "11" then
+ rx_done <= '0';
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+ end if;
+ end if;
+ else
+ --- [____]
+ if valid_byte_cntr /= "100" then -- No IDLE allowed, unless between two symbols: Something went wrong probably
+ valid_byte_cntr <= "000";
+ irregular_stream <= '0';
+ end if;
+ if done_cntr = "11" then
+ rx_done <= '0';
+ RXCHARISK_sr_done <= (others => '1');
+ RXCHARISvalid_sr_done <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+end process;
+
+RXDATA_u <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto 8) when mode_sel = '1' else -- x4 mode
+ RXDATA_sr_done(63 downto 32); -- x1 mode
+RXCHARISK_u <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1) when mode_sel = '1' else -- x4 mode
+ RXCHARISK_sr_done(7 downto 4); -- x1 mode
+RXCHARISvalid_u <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1) when mode_sel = '1' else -- x4 mode
+ RXCHARISvalid_sr_done(7 downto 4); -- x1 mode
+RXDATA_l <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto 0) when mode_sel = '1' else -- x4 mode
+ RXDATA_sr_done(31 downto 0); -- x1 mode
+RXCHARISK_l <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0) when mode_sel = '1' else -- x4 mode
+ RXCHARISK_sr_done(3 downto 0); -- x1 mode
+RXCHARISvalid_l <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0) when mode_sel = '1' else -- x4 mode
+ RXCHARISvalid_sr_done(3 downto 0); -- x1 mode
+
+-- RXDATA_u <= RXDATA_swap(63 downto 56) & RXDATA_swap(47 downto 40) & RXDATA_swap(31 downto 24) & RXDATA_swap(15 downto 8);
+-- RXCHARISK_u <= RXCHARISK_swap(7) & RXCHARISK_swap(5) & RXCHARISK_swap(3) & RXCHARISK_swap(1);
+-- RXDATA_l <= RXDATA_swap(55 downto 48) & RXDATA_swap(39 downto 32) & RXDATA_swap(23 downto 16) & RXDATA_swap(7 downto 0);
+-- RXCHARISK_l <= RXCHARISK_swap(6) & RXCHARISK_swap(4) & RXCHARISK_swap(2) & RXCHARISK_swap(0);
+-- RXCHARISvalid_u <= RXCHARISvalid_swap(7) & RXCHARISvalid_swap(5) & RXCHARISvalid_swap(3) & RXCHARISvalid_swap(1);
+-- RXCHARISvalid_l <= RXCHARISvalid_swap(6) & RXCHARISvalid_swap(4) & RXCHARISvalid_swap(2) & RXCHARISvalid_swap(0);
+
+upper_symbol_type <= SYMBOL_IDLE when RXCHARISK_u = "1111" and RXCHARISvalid_u = "1111" else
+ SYMBOL_CONTROL when RXCHARISK_u = "1000" and RXCHARISvalid_u = "1111" and (RXDATA_u(31 downto 24) = SC or RXDATA_u(31 downto 24) = PD) else
+ SYMBOL_DATA when RXCHARISK_u = "0000" and RXCHARISvalid_u = "1111" else
+ SYMBOL_ERROR;
+
+lower_symbol_type <= SYMBOL_IDLE when RXCHARISK_l = "1111" and RXCHARISvalid_l = "1111" else
+ SYMBOL_CONTROL when RXCHARISK_l = "1000" and RXCHARISvalid_l = "1111" and (RXDATA_l(31 downto 24) = SC or RXDATA_l(31 downto 24) = PD) else
+ SYMBOL_DATA when RXCHARISK_l = "0000" and RXCHARISvalid_l = "1111" else
+ SYMBOL_ERROR;
+
+--
+upper_symbol_not_idle <= '0' when upper_symbol_type = SYMBOL_IDLE else '1';
+lower_symbol_not_idle <= '0' when lower_symbol_type = SYMBOL_IDLE else '1';
+upper_symbol_not_error <= '0' when upper_symbol_type = SYMBOL_ERROR else '1';
+lower_symbol_not_error <= '0' when lower_symbol_type = SYMBOL_ERROR else '1';
+
+upper_symbol_valid <= upper_symbol_not_idle and upper_symbol_not_error;
+lower_symbol_valid <= lower_symbol_not_idle and lower_symbol_not_error;
+
+
+end RTL;
+---------------------------------------------------------------------------------------
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: pcs_tx_controller.vhd
+-- Rev: 0.0
+-- Description: This entity controls the TX stream
+--
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+entity pcs_tx_controller is
+ generic (
+ TCQ : time := 100 ps
+ );
+ port (
+ rst_n : in std_logic;
+ rio_clk : in std_logic; -- ~150 MHz
+ UCLK_x2 : in std_logic; -- 312,5 MHz
+ UCLK : in std_logic; -- 156,25 MHz
+ UCLK_x2_DV2 : in std_logic; -- 312,5 MHz @ x4 mode / 78,125 @ x1 (fallback mode)
+ UCLK_or_DV4 : in std_logic; -- 156,25 MHz @ x4 mode / 39,0625 @ x1 (fallback mode)
+ --
+ -- Interface to the RioSerial
+ outboundWrite_i : in std_logic;
+ outboundFull_o : out std_logic;
+ outboundSymbol_i : in std_logic_vector(33 downto 0);
+ -- outboundSymbolEmpty_i : in std_logic;
+ -- outboundSymbolRead_o : out std_logic;
+ -- outboundSymbol_i : in std_logic_vector(33 downto 0);
+ --
+ -- Interface to the GTX transceivers
+ TXDATA_o : out std_logic_vector(63 downto 0); -- N = 4
+ TXCHARISK_o : out std_logic_vector(7 downto 0);
+ --
+ -- Interface to the other blocks
+ send_ccs_i : in std_logic;
+ ccs_timer_rst_o : out std_logic;
+ send_idle_o : out std_logic_vector(1 downto 0);
+ send_K_i : in std_logic_vector(1 downto 0);
+ send_A_i : in std_logic_vector(1 downto 0);
+ send_R_i : in std_logic_vector(1 downto 0);
+ --
+ -- Interface to the port init
+ TXINHIBIT_02 : in std_logic;
+ TXINHIBIT_others : in std_logic;
+ port_initalized_i : in std_logic;
+ mode_sel_i : in std_logic;
+ mode_0_lane_sel_i : in std_logic
+
+ );
+end pcs_tx_controller;
+
+architecture RTL of pcs_tx_controller is
+
+-------------------------------------------------------------------------------
+COMPONENT pcs_tx_boudary_32b_in_64b_out
+ PORT (
+ rst : IN STD_LOGIC;
+ wr_clk : IN STD_LOGIC;
+ rd_clk : IN STD_LOGIC;
+ din : IN STD_LOGIC_VECTOR(33 DOWNTO 0);
+ wr_en : IN STD_LOGIC;
+ rd_en : IN STD_LOGIC;
+ dout : OUT STD_LOGIC_VECTOR(67 DOWNTO 0);
+ full : OUT STD_LOGIC;
+ empty : OUT STD_LOGIC;
+ almost_empty : out STD_LOGIC;
+ almost_full : out STD_LOGIC;
+ valid : OUT STD_LOGIC
+ );
+END COMPONENT;
+-------------------------------------------------------------------------------
+-- COMPONENT pcs_tx_boudary_32b_v2
+-- PORT (
+-- rst : IN STD_LOGIC;
+-- wr_clk : IN STD_LOGIC;
+-- rd_clk : IN STD_LOGIC;
+-- din : IN STD_LOGIC_VECTOR(33 DOWNTO 0);
+-- wr_en : IN STD_LOGIC;
+-- rd_en : IN STD_LOGIC;
+-- dout : OUT STD_LOGIC_VECTOR(33 DOWNTO 0);
+-- full : OUT STD_LOGIC;
+-- empty : OUT STD_LOGIC;
+-- almost_empty : OUT STD_LOGIC;
+-- valid : OUT STD_LOGIC
+-- );
+-- END COMPONENT;
+-------------------------------------------------------------------------------
+signal rst : std_logic:= '0';
+signal fragment_counter : std_logic_vector(9 downto 0) := (others => '0');
+signal outboundSymbolType : std_logic_vector(1 downto 0) := (others => '0');
+signal outboundSymbol : std_logic_vector(33 downto 0) := (others => '0');
+signal outboundSymbolRead : std_logic:= '0';
+signal non_idle : std_logic:= '0';
+signal decrement_frag_cntr : std_logic:= '0';
+
+signal tx_fifo_full : std_logic:= '0';
+signal symbol_empty : std_logic:= '0';
+signal symbol_almost_empty : std_logic:= '0';
+signal symbol_read : std_logic:= '0';
+signal symbol_valid : std_logic:= '0';
+-- signal symbol : std_logic_vector(33 downto 0) := (others => '0');
+signal symbol : std_logic_vector(67 downto 0) := (others => '0');
+signal symbol_u : std_logic_vector(33 downto 0) := (others => '0');
+signal symbol_l : std_logic_vector(33 downto 0) := (others => '0');
+-- signal symbol_type : std_logic_vector(1 downto 0) := (others => '0');
+signal symbol_type : std_logic_vector(3 downto 0) := (others => '0');
+signal symbol_type_u : std_logic_vector(1 downto 0) := (others => '0');
+signal symbol_type_l : std_logic_vector(1 downto 0) := (others => '0');
+
+signal TXDATA : std_logic_vector(63 downto 0); -- N = 4
+signal TXCHARISK : std_logic_vector(7 downto 0);
+signal TXDATA_u : std_logic_vector(31 downto 0);
+signal TXCHARISK_u : std_logic_vector(3 downto 0);
+signal TXDATA_l : std_logic_vector(31 downto 0);
+signal TXCHARISK_l : std_logic_vector(3 downto 0);
+
+signal TXDATA_u_idle : std_logic_vector(31 downto 0);
+signal TXDATA_l_idle : std_logic_vector(31 downto 0);
+
+signal word_switch : std_logic:= '0';
+signal lane_switch : std_logic_vector(1 downto 0) := (others => '0');
+signal cycle_switch : std_logic_vector(1 downto 0) := (others => '0');
+signal read_switch : std_logic_vector(1 downto 0) := (others => '0');
+
+signal send_idle_q : std_logic:= '0';
+signal send_idle_reg : std_logic_vector(1 downto 0) := (others => '0');
+signal send_idle : std_logic_vector(1 downto 0) := (others => '0');
+signal idle_char_type_0 : std_logic_vector(2 downto 0) := (others => '0');
+signal idle_char_type_1 : std_logic_vector(2 downto 0) := (others => '0');
+
+signal send_ccs_cntr : std_logic_vector(1 downto 0) := (others => '0');
+signal send_K : std_logic_vector(1 downto 0) := (others => '0');
+signal send_A : std_logic_vector(1 downto 0) := (others => '0');
+signal send_R : std_logic_vector(1 downto 0) := (others => '0');
+signal send_ccs : std_logic:= '0';
+signal send_ccs_q : std_logic:= '0';
+signal do_not_interrupt : std_logic:= '0';
+
+signal be_silent : std_logic:= '0';
+signal fifo_wr_selective : std_logic:= '0';
+signal fifo_wr_selective_q : std_logic:= '0';
+signal fifo_wr_always_even : std_logic:= '0';
+signal fifo_wr_odd_or_even : std_logic:= '0';
+signal fifo_wr_evenly : std_logic:= '0';
+signal outboundSymbolisData : std_logic:= '0';
+signal outboundSymbolisData_q : std_logic:= '0';
+
+signal outboundSymbol_q : std_logic_vector(33 downto 0) := (others => '0');
+signal fifo_wr_evenly_q : std_logic:= '0';
+-- signal send_K_ccs : std_logic:= '0';
+-- signal send_R_ccs : std_logic:= '0';
+-- signal send_K_q : std_logic:= '0';
+-- signal send_A_q : std_logic:= '0';
+-- signal send_R_q : std_logic:= '0';
+----------------------------------------------------------------------------------
+begin
+--
+rst <= not(rst_n);
+
+outboundSymbolType <= outboundSymbol_i(33 downto 32);
+-- Filtering the ERROR symbol out
+outboundSymbol <= outboundSymbol_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else
+ SYMBOL_IDLE & outboundSymbol_i(31 downto 0);
+
+fifo_wr_selective <= outboundWrite_i when (outboundSymbolType = SYMBOL_DATA or outboundSymbolType = SYMBOL_CONTROL) else '0';
+
+fifo_wr_always_even <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even);
+
+outboundSymbolisData <= '1' when outboundSymbolType = SYMBOL_DATA else '0';
+
+fifo_wr_evenly <= fifo_wr_selective or (fifo_wr_selective_q and fifo_wr_odd_or_even and not(outboundSymbolisData_q));
+
+-- Writing to the FIFO
+process(rio_clk)
+ begin
+ if rising_edge(rio_clk) then
+ fifo_wr_selective_q <= fifo_wr_selective;
+ outboundSymbolisData_q <= outboundSymbolisData;
+ if fifo_wr_selective = '1' then
+ fifo_wr_odd_or_even <= not(fifo_wr_odd_or_even);
+ elsif fifo_wr_selective_q = '1' then
+ fifo_wr_odd_or_even <= fifo_wr_odd_or_even and outboundSymbolisData_q; -- '0';
+ end if;
+
+ outboundSymbol_q <= outboundSymbol;
+ fifo_wr_evenly_q <= fifo_wr_evenly;
+ end if;
+end process;
+
+send_K <= send_K_i;
+send_A <= send_A_i;
+send_R <= send_R_i;
+
+-- idle_char_type <= send_K & send_A & send_R;
+idle_char_type_0 <= send_K(0) & send_A(0) & send_R(0);
+idle_char_type_1 <= send_K(1) & send_A(1) & send_R(1);
+
+be_silent <= '1' when TXINHIBIT_02 = '1' and TXINHIBIT_others = '1' else '0';
+
+-- symbol_type <= symbol(33 downto 32);
+symbol_type_u <= symbol_u(33 downto 32);
+symbol_type_l <= symbol_l(33 downto 32);
+
+symbol_u <= symbol(67 downto 34);
+symbol_l <= symbol(33 downto 0);
+
+send_idle(1) <= '1' when (send_ccs = '0') and
+ ((symbol_read = '1' and symbol_type_u = SYMBOL_IDLE) or
+ (symbol_read = '0') or
+ (port_initalized_i = '0'))
+ else
+ '0';
+
+send_idle(0) <= '1' when (send_ccs = '0') and
+ ((symbol_read = '1' and symbol_type_l = SYMBOL_IDLE) or
+ (symbol_read = '0') or
+ (port_initalized_i = '0'))
+ else
+ '0';
+
+send_idle_o <= send_idle; -- _reg;
+
+-- symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q);
+
+-- Pipelining
+process(UCLK) -- _x2
+ begin
+ if rising_edge(UCLK) then
+ send_ccs <= not(do_not_interrupt) and send_ccs_i; -- will be high only during real CCS transmission
+ -- send_idle_reg <= send_idle;
+ end if;
+end process;
+
+-- Reading from the FIFO
+process(UCLK_or_DV4) -- UCLK_x2_DV2
+ begin
+ if rising_edge(UCLK_or_DV4) then
+ -- case symbol_read is
+ -- when '0' =>
+ -- symbol_read <= not(symbol_empty) and not(send_ccs) and not(send_ccs_q); -- after TCQ;
+ -- when '1' =>
+ -- symbol_read <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q);
+ -- when others =>
+ -- symbol_read <= '0'; -- after TCQ;
+ -- end case;
+
+ end if;
+end process;
+
+tx_boundary_fifo : pcs_tx_boudary_32b_in_64b_out -- FWFT FIFO
+ PORT MAP (
+ rst => rst,
+
+ wr_clk => rio_clk,
+ wr_en => fifo_wr_evenly_q, --fifo_wr_always_even, --outboundWrite_i,
+ din => outboundSymbol_q,
+ full => open, -- outboundFull_o,
+ almost_full => outboundFull_o,
+
+ rd_clk => UCLK_or_DV4,
+ rd_en => symbol_read,
+ dout => symbol,
+ empty => symbol_empty,
+ almost_empty => symbol_almost_empty,
+ valid => symbol_valid
+ );
+
+-- FIFO read / TX output process
+process(rst_n, UCLK) -- UCLK_x2
+ begin
+ if rst_n = '0' then
+
+ ccs_timer_rst_o <= '0';
+ do_not_interrupt <= '0';
+ TXDATA_u <= (others => '0');
+ TXCHARISK_u <= (others => '0');
+ TXDATA_l <= (others => '0');
+ TXCHARISK_l <= (others => '0');
+ cycle_switch <= (others => '0');
+ read_switch <= (others => '0');
+ symbol_read <= '0';
+
+ elsif rising_edge(UCLK) then
+
+ if be_silent = '0' then -- Transmitters are NOT inhibitied
+ if send_ccs = '1' or send_ccs_q = '1' then -- Transmitting the clock compensation sequence (ccs) = |K|,|R|,|R|,|R|
+ symbol_read <= '0';
+ if send_ccs_q = '0' then
+ TXDATA_u <= K_column;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= R_column;
+ TXCHARISK_l <= (others => '1');
+ ccs_timer_rst_o <= '1';
+ else
+ TXDATA_u <= R_column;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= R_column;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ else -- Transmitting the IDLE sequence or the CONTROL/DATA symbols
+
+ read_switch <= read_switch + '1';
+ if read_switch = "00" then
+ case symbol_read is
+ when '0' =>
+ symbol_read <= not(symbol_empty); -- and not(send_ccs) and not(send_ccs_q); -- after TCQ;
+ do_not_interrupt <= not(symbol_empty);
+ when '1' =>
+ symbol_read <= not(symbol_almost_empty); -- after TCQ; -- and not(send_ccs) and not(send_ccs_q);
+ do_not_interrupt <= not(symbol_almost_empty);
+ when others =>
+ symbol_read <= '0'; -- after TCQ;
+ do_not_interrupt <= '0';
+ end case;
+ end if;
+
+ ccs_timer_rst_o <= '0';
+ if symbol_read = '1' then -- two symbols have been read, at least one of them is non-idle, they should be forwarded in 1 or 4 cycles
+ case mode_sel_i is
+ when '1' => -- Lane stripping (x4 mode: rd_clk = UCLK)
+ case symbol_type_u is
+ when SYMBOL_DATA =>
+ TXDATA_u <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0);
+ TXCHARISK_u <= (others => '0');
+ when SYMBOL_CONTROL =>
+ TXDATA_u <= symbol_u(31 downto 24) & symbol_u(23 downto 16) & symbol_u(15 downto 8) & symbol_u(7 downto 0);
+ TXCHARISK_u <= "1000";
+ when SYMBOL_IDLE =>
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ when others =>
+ -- dummy
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ end case;
+ case symbol_type_l is
+ when SYMBOL_DATA =>
+ TXDATA_l <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0);
+ TXCHARISK_l <= (others => '0');
+ when SYMBOL_CONTROL =>
+ TXDATA_l <= symbol_l(31 downto 24) & symbol_l(23 downto 16) & symbol_l(15 downto 8) & symbol_l(7 downto 0);
+ TXCHARISK_l <= "1000";
+ when SYMBOL_IDLE =>
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ when others =>
+ -- dummy
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end case;
+ when '0' => -- Slow motion read (x1 mode: rd_clk = UCLK_DV4)
+ cycle_switch <= cycle_switch + '1';
+ -- Cycle | Symbol part to be sent
+ ---------|----------------------
+ -- 00 | symbol_u(31 downto 16)
+ -- 01 | symbol_u(15 downto 0)
+ -- 10 | symbol_l(31 downto 16)
+ -- 11 | symbol_l(15 downto 0)
+ case cycle_switch(1) is
+ when '0' =>
+ case cycle_switch(0) is
+ when '0' => -- 00
+ if symbol_type_u /= SYMBOL_IDLE then
+ TXDATA_u <= symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24) & symbol_u(31 downto 24);
+ if symbol_type_u = SYMBOL_DATA then
+ TXCHARISK_u <= (others => '0');
+ else -- if symbol_type_u = SYMBOL_CONTROL then
+ TXCHARISK_u <= (others => '1');
+ end if;
+ TXDATA_l <= symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16) & symbol_u(23 downto 16);
+ TXCHARISK_l <= (others => '0');
+ else -- if symbol_type_u = SYMBOL_IDLE then
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ when '1' => -- 01
+ if symbol_type_u /= SYMBOL_IDLE then
+ TXDATA_u <= symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8) & symbol_u(15 downto 8);
+ TXCHARISK_u <= (others => '0'); -- This is the second part: does not matter control or data
+ TXDATA_l <= symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0) & symbol_u(7 downto 0);
+ TXCHARISK_l <= (others => '0');
+ else -- if symbol_type_u = SYMBOL_IDLE then
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ when others =>
+ -- dummy
+ end case;
+ when '1' =>
+ case cycle_switch(0) is
+ when '0' =>
+ if symbol_type_l /= SYMBOL_IDLE then
+ TXDATA_u <= symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24) & symbol_l(31 downto 24);
+ if symbol_type_l = SYMBOL_DATA then
+ TXCHARISK_u <= (others => '0');
+ else -- if symbol_type_l = SYMBOL_CONTROL then
+ TXCHARISK_u <= (others => '1');
+ end if;
+ TXDATA_l <= symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16) & symbol_l(23 downto 16);
+ TXCHARISK_l <= (others => '0');
+ else -- if symbol_type_l = SYMBOL_IDLE then
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ when '1' =>
+ if symbol_type_l /= SYMBOL_IDLE then
+ TXDATA_u <= symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8) & symbol_l(15 downto 8);
+ TXCHARISK_u <= (others => '0'); -- This is the second part: does not matter control or data
+ TXDATA_l <= symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0) & symbol_l(7 downto 0);
+ TXCHARISK_l <= (others => '0');
+ else -- if symbol_type_l = SYMBOL_IDLE then
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ when others =>
+ -- dummy
+ end case;
+ when others =>
+ -- dummy
+ end case;
+
+ when others =>
+ -- dummy
+ end case;
+ -----------------------------------------------------------------------------
+ else -- No Symbols are present at the FIFO output: Transmitting an idle sequence: |K| or |A| or |R|
+ TXDATA_u <= TXDATA_u_idle;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= TXDATA_l_idle;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ end if;
+ else -- Transmitters are inhibitied
+ TXDATA_u <= x"BCBCBCBC" ;
+ TXCHARISK_u <= (others => '1');
+ TXDATA_l <= x"FDFDFDFD" ;
+ TXCHARISK_l <= (others => '1');
+ end if;
+ end if;
+end process;
+
+-- Combinational idle drive process
+process(idle_char_type_0, idle_char_type_1)
+ begin
+ case idle_char_type_1 is
+ when "100" => -- |K| (~%50)
+ TXDATA_u_idle <= K_column;
+
+ when "010" => -- |A| (1/16 .. 1/32)
+ TXDATA_u_idle <= A_column;
+
+ when "001" => -- |R| (~%50)
+ TXDATA_u_idle <= R_column;
+
+ when others =>
+ -- dummy
+ TXDATA_u_idle <= K_column;
+ end case;
+ case idle_char_type_0 is
+ when "100" => -- |K| (~%50)
+ TXDATA_l_idle <= K_column;
+
+ when "010" => -- |A| (1/16 .. 1/32)
+ TXDATA_l_idle <= A_column;
+
+ when "001" => -- |R| (~%50)
+ TXDATA_l_idle <= R_column;
+
+ when others =>
+ -- dummy
+ TXDATA_l_idle <= R_column;
+ end case;
+end process;
+
+-- TXDATA buffering by UCLK
+process(UCLK)
+ begin
+ if rising_edge(UCLK) then
+ ------------------
+ -- MUST BE SWAPPED
+ TXDATA_o <= TXDATA_u( 7 downto 0) & TXDATA_l( 7 downto 0) & TXDATA_u(15 downto 8) & TXDATA_l(15 downto 8)
+ & TXDATA_u(23 downto 16) & TXDATA_l(23 downto 16) & TXDATA_u(31 downto 24) & TXDATA_l(31 downto 24);
+ TXCHARISK_o <= TXCHARISK_u(0) & TXCHARISK_l(0) & TXCHARISK_u(1) & TXCHARISK_l(1) & TXCHARISK_u(2) & TXCHARISK_l(2) & TXCHARISK_u(3) & TXCHARISK_l(3);
+ ------------------
+ end if;
+end process;
+
+-- Delaying send_ccs
+process(UCLK)
+ begin
+ if rising_edge(UCLK) then
+ if be_silent = '0' then
+ send_ccs_q <= send_ccs; ---
+ else
+ send_ccs_q <= '0';
+ end if;
+ end if;
+end process;
+
+end RTL;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: port_init_fsms.vhd
+-- Rev: 0.0
+-- Description: This entity does the 1x/Nx port init according to the
+-- RIO Sepec. Part-6, subchapter 4.2
+--
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+--use work.rio_common_sim.all;
+
+entity port_init_fsms is
+ generic (
+ TCQ : time := 100 ps
+ );
+ port (
+ rst_n : in std_logic;
+ UCLK_x2 : in std_logic;
+ UCLK : in std_logic;
+ UCLK_DV4 : in std_logic;
+ UCLK_DV_1024 : in std_logic;
+
+ force_reinit : in std_logic:='0'; -- force retraining
+ mode_sel : out std_logic; -- 0: x1 fallback mode / 1: xN Mode
+ mode_0_lane_sel : out std_logic; -- If mode_sel = 0 then 0: Lane 0 is active(R), 1: Lane 2 is active else don't care
+ port_initalized : out std_logic; -- 1: Port initialization is successfully complete
+ lane_sync : out std_logic_vector(N-1 downto 0); -- Lane is synchoronised
+ RXCHARISvalid : out std_logic_vector(N*2-1 downto 0);
+
+ -- GTXRESET : out std_logic;
+ TXINHIBIT_02 : out std_logic;
+ TXINHIBIT_others : out std_logic;
+ ENCHANSYNC : out std_logic;
+ -- TXDATA : out std_logic_vector(N*16-1 downto 0);
+ -- TXCHARISK : out std_logic_vector(N*2-1 downto 0);
+ PLLLKDET : in std_logic;
+ RXDATA : in std_logic_vector(N*16-1 downto 0);
+ RXCHARISK : in std_logic_vector(N*2-1 downto 0);
+ RXCHARISCOMMA : in std_logic_vector(N*2-1 downto 0);
+ RXBYTEISALIGNED : in std_logic_vector(N-1 downto 0);
+ RXBYTEREALIGN : in std_logic_vector(N-1 downto 0);
+ RXELECIDLE : in std_logic_vector(N-1 downto 0);
+ RXDISPERR : in std_logic_vector(N*2-1 downto 0);
+ RXNOTINTABLE : in std_logic_vector(N*2-1 downto 0);
+ RXBUFERR : in std_logic;
+ RXBUFRST : out std_logic;
+ CHBONDDONE : in std_logic_vector(N-1 downto 0)
+ );
+end port_init_fsms;
+
+architecture rtl of port_init_fsms is
+-------------------------------------------------------------------------------------------------------------------------------------------
+-- Lane_Synchronization State Machine
+type lane_sync_states is (NO_SYNC, NO_SYNC_1, NO_SYNC_2, NO_SYNC_2a, NO_SYNC_2b, NO_SYNC_3, SYNC, SYNCa, SYNCb, SYNC_1, SYNC_2, SYNC_2a, SYNC_2b, SYNC_3, SYNC_4);
+type lane_sync_states_array is array (N-1 downto 0) of lane_sync_states;
+
+signal lane_sync_state_n : lane_sync_states_array := (others => NO_SYNC);
+signal lane_sync_n : std_logic_vector(N-1 downto 0) := (others => '0');
+signal Kcounter_n : Kcounter_array_type := (others => (others => '0'));
+signal Vcounter_n : Vcounter_array_type := (others => (others => '0'));
+signal Icounter_n : Icounter_array_type := (others => (others => '0'));
+signal code_group_valid : std_logic_vector(N*2-1 downto 0) := (others => '0');
+-------------------------------------------------------------------------------------------------------------------------------------------
+-- Lane_Alignment State Machine
+type lane_alignment_states is (NOT_ALIGNED, NOT_ALIGNED_1, NOT_ALIGNED_2, ALIGNED, ALIGNED_1, ALIGNED_2, ALIGNED_3);
+
+signal lane_alignment_state : lane_alignment_states := NOT_ALIGNED;
+signal N_lanes_aligned : std_logic := '0';
+signal Acounter : std_logic_vector(2 downto 0) := (others => '0');
+signal Mcounter : Mcounter_type := (others => '0');
+signal lane_alignment_reset : std_logic := '0';
+signal N_lane_sync : std_logic := '0';
+constant N_lanes_all_high : std_logic_vector(N-1 downto 0) := (others => '1');
+constant N_lanes_all_low : std_logic_vector(N-1 downto 0) := (others => '0');
+
+signal A_column_valid : std_logic := '0';
+signal align_error : std_logic := '0';
+signal A_column_valid_upper : std_logic := '0';
+signal align_error_upper : std_logic := '0';
+signal A_column_valid_lower : std_logic := '0';
+signal align_error_lower : std_logic := '0';
+
+signal RXCHARIS_A_upper : std_logic_vector(N-1 downto 0) := (others => '0');
+signal RXCHARIS_A_lower : std_logic_vector(N-1 downto 0) := (others => '0');
+-------------------------------------------------------------------------------------------------------------------------------------------
+-- begin --dummy
+-- 1x/Nx Mode Init State Machine
+type mode_init_states is (SILENT, SEEK, DISCOVERY, x1_RECOVERY, Nx_MODE, x1_MODE_LANE0, x1_MODE_LANE2);
+
+signal mode_init_state : mode_init_states := SILENT;
+signal lanes02_drvr_oe : std_logic := '0';
+signal N_lanes_drvr_oe : std_logic := '0';
+signal Nx_mode_active : std_logic := '0';
+signal receive_lane2 : std_logic := '0';
+signal force_reinit_reg : std_logic := '0';
+signal force_reinit_clear : std_logic := '0';
+
+signal silence_timer_en : std_logic := '0';
+signal silence_timer_done : std_logic := '0';
+signal silence_timer : std_logic_vector(4 downto 0) := (others => '0');
+
+signal disc_tmr_en : std_logic := '0';
+signal disc_tmr_done : std_logic := '0';
+signal disc_tmr : std_logic_vector(15 downto 0) := (others => '0');
+
+signal port_initalized_reg : std_logic := '0';
+
+signal idle_selected : std_logic := '1'; -- Only IDLE1 is to be used
+signal Nx_mode_enabled : std_logic := '1'; -- Nx mode is to be always enabled
+signal force_1x_mode : std_logic := '0'; -- don't force 1x mode
+signal force_laneR : std_logic := '0'; -- don't care, when force_1x_mode = 0
+
+signal lane_ready_n : std_logic_vector(N-1 downto 0) := (others => '0');
+signal rcvr_trained_n : std_logic_vector(N-1 downto 0) := (others => '0');
+signal N_lanes_ready : std_logic := '0';
+
+signal rxbufrst_cntr : std_logic_vector(2 downto 0) := (others => '0');
+signal rxbuferr_reg : std_logic := '0';
+-------------------------------------------------------------------------------------------------------------------------------------------
+begin
+
+lane_sync <= lane_sync_n;
+----------------------------------------------------------------
+-- Figure 4-14. Lane_Synchronization State Machine for N Lanes
+GEN_LANE_SYNC_FSM: for i in 0 to N-1 generate
+
+code_group_valid(i*2) <= not(RXNOTINTABLE(i*2) ) and not(RXDISPERR(i*2) );
+code_group_valid(i*2+1) <= not(RXNOTINTABLE(i*2+1)) and not(RXDISPERR(i*2+1));
+
+RXCHARISvalid(i*2) <= code_group_valid(i*2) ;
+RXCHARISvalid(i*2+1) <= code_group_valid(i*2+1);
+
+process(rst_n, UCLK) -- (UCLK_x2) --
+ begin
+
+ if rst_n = '0' then
+
+ lane_sync_state_n(i) <= NO_SYNC;
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+
+ elsif rising_edge(UCLK) then
+
+ case lane_sync_state_n(i) is
+ when NO_SYNC =>
+ -- change(signal_detect[n])
+ if RXELECIDLE(i) = '1' then
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+ -- signal_detect[n] & /COMMA/ [ KK-- ] : /K/ is being detected at the upper half
+ elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then
+ -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected also at the lower half
+ if (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then
+ lane_sync_state_n(i) <= NO_SYNC_2;
+ Kcounter_n(i) <= Kcounter_n(i) + "10";
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ -- signal_detect[n] [ --VV ] : At the lower half: no comma, but valid
+ elsif (code_group_valid(i*2) = '1') then
+ lane_sync_state_n(i) <= NO_SYNC_2;
+ Kcounter_n(i) <= Kcounter_n(i) + '1';
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ -- do nothing
+ else
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+ end if;
+ ----------------------------------------------------------------------------------------------
+ -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected only at the lower half
+ elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then
+ lane_sync_state_n(i) <= NO_SYNC_2;
+ Kcounter_n(i) <= Kcounter_n(i) + '1';
+ Vcounter_n(i) <= Vcounter_n(i) + '1';
+ ----------------------------------------------------------------------------------------------
+ -- !signal_detect[n] | !/COMMA/
+ else
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+ end if;
+ -- -- change(signal_detect[n])
+ -- if RXELECIDLE(i) = '1' then
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- Vcounter_n(i) <= (others => '0');
+ -- -- signal_detect[n] & /COMMA/ [ KK-- ] : /K/ is being detected at the upper half
+ -- elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then
+ -- lane_sync_state_n(i) <= NO_SYNC_2a;
+ -- Kcounter_n(i) <= Kcounter_n(i) + '1';
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- signal_detect[n] & /COMMA/ [ --KK ] : /K/ is being detected at the lower half
+ -- elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then
+ -- lane_sync_state_n(i) <= NO_SYNC_2b;
+ -- Kcounter_n(i) <= Kcounter_n(i) + '1';
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- !signal_detect[n] | !/COMMA/
+ -- else
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- Vcounter_n(i) <= (others => '0');
+ -- end if;
+
+ -- when NO_SYNC_1 =>
+
+ when NO_SYNC_2 =>
+ -- [ IIXX or XXII ] -- One of both /INVALID/
+ if (code_group_valid(i*2) = '0' or code_group_valid(i*2+1) = '0') then
+ lane_sync_state_n(i) <= NO_SYNC;
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+ -- [ KKKK ] -- Both /COMMA/
+ elsif (RXCHARISCOMMA(i*2) = '1' and RXCHARISCOMMA(i*2+1) = '1') then
+ -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1)
+ if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then
+ lane_sync_state_n(i) <= SYNC;
+ -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin)
+ else
+ Kcounter_n(i) <= Kcounter_n(i) + "10";
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ end if;
+ -- [ KKVV or VVKK ] -- One of both /COMMA/
+ elsif (RXCHARISCOMMA(i*2) = '1' or RXCHARISCOMMA(i*2+1) = '1') then
+ -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1)
+ if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then
+ lane_sync_state_n(i) <= SYNC;
+ -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin)
+ else
+ Kcounter_n(i) <= Kcounter_n(i) + '1' ;
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ end if;
+
+ -- [ VVVV ] -- None of both /COMMA/, but both /VALID/
+ else -- if RXCHARISCOMMA(i*2) = '0') and RXCHARISCOMMA(i*2+1) = '0') then
+ -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1)
+ if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then
+ lane_sync_state_n(i) <= SYNC;
+ -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin)
+ else
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ end if;
+ end if;
+
+ -- when NO_SYNC_2a =>
+ -- -- !(/COMMA/|/INVALID/)
+ -- if (code_group_valid(i*2) = '1' and not(RXCHARISCOMMA(i*2) = '1')) then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC")) then
+ -- lane_sync_state_n(i) <= NO_SYNC_2b;
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- /COMMA/
+ -- elsif (code_group_valid(i*2) = '1' and RXCHARISCOMMA(i*2) = '1') then --RXCHARISK(i*2) = '1' and RXDATA(i*16+7 downto i*16) = x"BC") then
+ -- -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1)
+ -- if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then
+ -- lane_sync_state_n(i) <= SYNCb;
+ -- -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin)
+ -- else
+ -- lane_sync_state_n(i) <= NO_SYNC_2b;
+ -- Kcounter_n(i) <= Kcounter_n(i) + '1';
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- end if;
+ -- -- /INVALID/
+ -- elsif (code_group_valid(i*2) = '0') then
+ -- lane_sync_state_n(i) <= NO_SYNC;
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- Vcounter_n(i) <= (others => '0');
+ -- end if;
+ --
+ -- when NO_SYNC_2b =>
+ -- -- !(/COMMA/|/INVALID/)
+ -- if (code_group_valid(i*2+1) = '1' and not(RXCHARISCOMMA(i*2+1) = '1')) then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC")) then
+ -- lane_sync_state_n(i) <= NO_SYNC_2a;
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- /COMMA/
+ -- elsif (code_group_valid(i*2+1) = '1' and RXCHARISCOMMA(i*2+1) = '1') then --RXCHARISK(i*2+1) = '1' and RXDATA(i*16+15 downto i*16+8) = x"BC") then
+ -- -- (Kcounter[n] > 126) & (Vcounter[n] > Vmin-1)
+ -- if Kcounter_n(i) >= Kmin and Vcounter_n(i) >= Vmin then
+ -- lane_sync_state_n(i) <= SYNCa;
+ -- -- (Kcounter[n] < 127) | (Vcounter[n] < Vmin)
+ -- else
+ -- lane_sync_state_n(i) <= NO_SYNC_2a;
+ -- Kcounter_n(i) <= Kcounter_n(i) + '1';
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- end if;
+ -- -- /INVALID/
+ -- elsif (code_group_valid(i*2+1) = '0') then
+ -- lane_sync_state_n(i) <= NO_SYNC;
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- Vcounter_n(i) <= (others => '0');
+ -- end if;
+
+ -- when NO_SYNC_3 =>
+
+ when SYNC =>
+ -- Both /VALID/
+ if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then
+ lane_sync_n(i) <= '1';
+ Icounter_n(i) <= (others => '0');
+ -- One of both /INVALID/
+ elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then
+ Icounter_n(i) <= Icounter_n(i) + '1';
+ lane_sync_state_n(i) <= SYNC_2;
+ -- Both /INVALID/
+ else
+ Icounter_n(i) <= Icounter_n(i) + "10";
+ lane_sync_state_n(i) <= SYNC_2;
+ end if;
+ --
+ -- when SYNCa =>
+ -- -- /INVALID/
+ -- if (code_group_valid(i*2) = '0') then
+ -- Icounter_n(i) <= Icounter_n(i) + '1';
+ -- lane_sync_state_n(i) <= SYNC_2b;
+ -- -- /VALID/
+ -- else
+ -- lane_sync_state_n(i) <= SYNCb;
+ -- lane_sync_n(i) <= '1';
+ -- Icounter_n(i) <= (others => '0');
+ -- end if;
+ --
+ -- when SYNCb =>
+ -- -- /INVALID/
+ -- if (code_group_valid(i*2+1) = '0') then
+ -- Icounter_n(i) <= Icounter_n(i) + '1';
+ -- lane_sync_state_n(i) <= SYNC_2a;
+ -- -- /VALID/
+ -- else
+ -- lane_sync_state_n(i) <= SYNCa;
+ -- lane_sync_n(i) <= '1';
+ -- Icounter_n(i) <= (others => '0');
+ -- end if;
+
+ -- when SYNC_1 =>
+
+ when SYNC_2 =>
+ -- Both /VALID/
+ if (code_group_valid(i*2) = '1' and code_group_valid(i*2+1) = '1') then
+ Vcounter_n(i) <= Vcounter_n(i) + "10";
+ -- (Vcounter[n] < 255)
+ if Vcounter_n(i) < x"FF" then
+ -- do nothing
+ lane_sync_state_n(i) <= SYNC_2;
+ -- (Vcounter[n] = 255)
+ else
+ Icounter_n(i) <= Icounter_n(i) - '1';
+ Vcounter_n(i) <= (others => '0');
+ -- (Icounter[n] > 0)
+ if Icounter_n(i) > Ione then
+ -- do nothing
+ lane_sync_state_n(i) <= SYNC_2;
+ -- (Icounter[n] = 0)
+ else
+ lane_sync_state_n(i) <= SYNC;
+ end if;
+ end if;
+ -- One of both /INVALID/
+ elsif (code_group_valid(i*2) = '1' or code_group_valid(i*2+1) = '1') then
+ Icounter_n(i) <= Icounter_n(i) + '1';
+ Vcounter_n(i) <= (others => '0');
+ -- (Icounter[n] = Imax)
+ if Icounter_n(i) = Imax then
+ lane_sync_state_n(i) <= NO_SYNC;
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ -- (Icounter[n] < Imax)
+ else
+ -- do nothing
+ lane_sync_state_n(i) <= SYNC_2;
+ end if;
+ -- Both /INVALID/
+ else
+ Icounter_n(i) <= Icounter_n(i) + "10";
+ Vcounter_n(i) <= (others => '0');
+ -- (Icounter[n] = Imax)
+ if Icounter_n(i) = Imax then
+ lane_sync_state_n(i) <= NO_SYNC;
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ -- (Icounter[n] < Imax)
+ else
+ -- do nothing
+ lane_sync_state_n(i) <= SYNC_2;
+ end if;
+ end if;
+ ----------------------------------------------
+
+ -- when SYNC_2a =>
+ -- -- /INVALID/
+ -- if (code_group_valid(i*2+1) = '0') then
+ -- Icounter_n(i) <= Icounter_n(i) + '1';
+ -- Vcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] = Imax)
+ -- if Icounter_n(i) = Imax then
+ -- lane_sync_state_n(i) <= NO_SYNC;
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] < Imax)
+ -- else
+ -- lane_sync_state_n(i) <= SYNC_2b;
+ -- end if;
+ -- -- /VALID/
+ -- else
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- (Vcounter[n] < 255)
+ -- if Vcounter_n(i) < x"FF" then
+ -- lane_sync_state_n(i) <= SYNC_2b;
+ -- -- (Vcounter[n] = 255)
+ -- else
+ -- Icounter_n(i) <= Icounter_n(i) - '1';
+ -- Vcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] > 0)
+ -- if Icounter_n(i) > Izero then
+ -- lane_sync_state_n(i) <= SYNC_2b;
+ -- -- (Icounter[n] = 0)
+ -- else
+ -- lane_sync_state_n(i) <= SYNCb;
+ -- end if;
+ -- end if;
+ -- end if;
+ --
+ -- when SYNC_2b =>
+ -- -- /INVALID/
+ -- if (code_group_valid(i*2+1) = '0') then
+ -- Icounter_n(i) <= Icounter_n(i) + '1';
+ -- Vcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] = Imax)
+ -- if Icounter_n(i) = Imax then
+ -- lane_sync_state_n(i) <= NO_SYNC;
+ -- lane_sync_n(i) <= '0';
+ -- Kcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] < Imax)
+ -- else
+ -- lane_sync_state_n(i) <= SYNC_2a;
+ -- end if;
+ -- -- /VALID/
+ -- else
+ -- Vcounter_n(i) <= Vcounter_n(i) + '1';
+ -- -- (Vcounter[n] < 255)
+ -- if Vcounter_n(i) < x"FF" then
+ -- lane_sync_state_n(i) <= SYNC_2a;
+ -- -- (Vcounter[n] = 255)
+ -- else
+ -- Icounter_n(i) <= Icounter_n(i) - '1';
+ -- Vcounter_n(i) <= (others => '0');
+ -- -- (Icounter[n] > 0)
+ -- if Icounter_n(i) > Izero then
+ -- lane_sync_state_n(i) <= SYNC_2a;
+ -- -- (Icounter[n] = 0)
+ -- else
+ -- lane_sync_state_n(i) <= SYNCa;
+ -- end if;
+ -- end if;
+ -- end if;
+
+ -- when SYNC_3 =>
+
+ -- when SYNC_4 =>
+
+ when others =>
+ lane_sync_state_n(i) <= NO_SYNC;
+ lane_sync_n(i) <= '0';
+ Kcounter_n(i) <= (others => '0');
+ Vcounter_n(i) <= (others => '0');
+
+ end case;
+ end if;
+end process;
+
+end generate GEN_LANE_SYNC_FSM;
+----------------------------------------------------------------
+-- Figure 4-15. Lane_Alignment State Machine (for N lanes)
+
+N_lane_sync <= '1' when lane_sync_n = N_lanes_all_high else '0';
+lane_alignment_reset <= N_lane_sync and rst_n;
+A_column_valid_upper <= '1' when (RXCHARIS_A_upper = N_lanes_all_high) else '0';
+A_column_valid_lower <= '1' when (RXCHARIS_A_lower = N_lanes_all_high) else '0';
+A_column_valid <= A_column_valid_upper or A_column_valid_lower;
+align_error_upper <= '1' when (RXCHARIS_A_upper /= N_lanes_all_low) and (RXCHARIS_A_upper /= N_lanes_all_high) else '0';
+align_error_lower <= '1' when (RXCHARIS_A_lower /= N_lanes_all_low) and (RXCHARIS_A_lower /= N_lanes_all_high) else '0';
+align_error <= align_error_upper or align_error_lower;
+GEN_CHAR_A_CHECKER: for i in 0 to N-1 generate
+RXCHARIS_A_upper(i) <= '1' when (code_group_valid(i*2+1) = '1') and (RXCHARISK(i*2+1) = '1') and (RXDATA(i*16+15 downto i*16+8) = A_align) else '0';
+RXCHARIS_A_lower(i) <= '1' when (code_group_valid(i*2) = '1' ) and (RXCHARISK(i*2) = '1' ) and (RXDATA(i*16+7 downto i*16 ) = A_align) else '0';
+end generate GEN_CHAR_A_CHECKER;
+
+process(lane_alignment_reset, UCLK)
+ begin
+
+ if lane_alignment_reset = '0' then
+
+ lane_alignment_state <= NOT_ALIGNED;
+ N_lanes_aligned <= '0';
+ Acounter <= (others => '0');
+ -- Mcounter <= (others => '0');
+
+ elsif rising_edge(UCLK) then
+
+ -- if lane_alignment_reset = '1' then
+
+ case lane_alignment_state is
+ when NOT_ALIGNED =>
+ -- N_lane_sync & ||A||
+ if N_lane_sync = '1' and A_column_valid = '1' then
+ Acounter <= Acounter + '1';
+ lane_alignment_state <= NOT_ALIGNED_2;
+ end if;
+
+ -- when NOT_ALIGNED_1 =>
+
+ when NOT_ALIGNED_2 =>
+ -- align_error
+ if align_error = '1' then
+ lane_alignment_state <= NOT_ALIGNED;
+ N_lanes_aligned <= '0';
+ Acounter <= (others => '0');
+ -- ||A||
+ elsif A_column_valid = '1' then
+ Acounter <= Acounter + '1';
+ -- Acounter = 4
+ if Acounter = "100" then
+ lane_alignment_state <= ALIGNED;
+ -- Acounter < 4
+ else
+ lane_alignment_state <= NOT_ALIGNED_2;
+ end if;
+ -- !align_error & !||A||
+ else
+ -- Do nothing: Wait for the next column
+ end if;
+
+ when ALIGNED =>
+ N_lanes_aligned <= '1';
+ Mcounter <= (others => '0');
+ -- align_error
+ if align_error = '1' then
+ Acounter <= (others => '0');
+ Mcounter <= Mcounter + '1';
+ lane_alignment_state <= ALIGNED_2;
+ -- !(align_error)
+ else
+ -- Do nothing extra: Wait for the next column
+ end if;
+
+ -- when ALIGNED_1 =>
+
+ when ALIGNED_2 =>
+ -- align_error
+ if align_error = '1' then
+ Acounter <= (others => '0');
+ Mcounter <= Mcounter + '1';
+ -- Mcounter = Mmax
+ if Mcounter = Mmax then
+ lane_alignment_state <= NOT_ALIGNED;
+ N_lanes_aligned <= '0';
+ -- Mcounter < Mmax
+ else
+ -- Do nothing extra: Wait for the next column
+ end if;
+ -- ||A||
+ elsif A_column_valid = '1' then
+ Acounter <= Acounter + '1';
+ -- Acounter = 4
+ if Acounter = "100" then
+ lane_alignment_state <= ALIGNED;
+ -- Acounter < 4
+ else
+ -- Do nothing extra: Wait for the next column
+ end if;
+ -- !align_error & !||A||
+ else
+ -- Do nothing: Wait for the next column
+ end if;
+
+ -- when ALIGNED_3 =>
+
+ when others =>
+ lane_alignment_state <= NOT_ALIGNED;
+ N_lanes_aligned <= '0';
+ Acounter <= (others => '0');
+ Mcounter <= (others => '0');
+
+ end case;
+ -- else
+ -- lane_alignment_state <= NOT_ALIGNED;
+ -- N_lanes_aligned <= '0';
+ -- Acounter <= (others => '0');
+ -- end if;
+ end if;
+end process;
+
+-- Figure 4-18. 1x/Nx_Initialization State Machine for N = 4
+TXINHIBIT_02 <= not(lanes02_drvr_oe);
+TXINHIBIT_others <= not(N_lanes_drvr_oe);
+rcvr_trained_n <= CHBONDDONE; -- TBD
+lane_ready_n <= lane_sync_n and rcvr_trained_n;
+-- lane_ready_n <= lane_sync_n; -- and rcvr_trained_n;
+N_lanes_ready <= '1' when N_lanes_aligned = '1' and lane_ready_n = N_lanes_all_high else '0';
+
+-- process(UCLK)
+-- begin
+-- if rising_edge(UCLK) then
+-- mode_sel <= Nx_mode_active;
+-- mode_0_lane_sel <= receive_lane2;
+-- port_initalized <= port_initalized_reg;
+-- end if;
+-- end process;
+mode_sel <= Nx_mode_active;
+mode_0_lane_sel <= receive_lane2;
+port_initalized <= port_initalized_reg;
+
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+
+ mode_init_state <= SILENT;
+ disc_tmr_en <= '0';
+ lanes02_drvr_oe <= '0';
+ N_lanes_drvr_oe <= '0';
+ port_initalized_reg <= '0';
+ Nx_mode_active <= '0';
+ receive_lane2 <= '0';
+ force_reinit_clear <= '0';
+ silence_timer_en <= '0';
+ idle_selected <= '1';
+
+ elsif rising_edge(UCLK) then
+ case mode_init_state is
+
+ when SILENT =>
+ disc_tmr_en <= '0';
+ lanes02_drvr_oe <= '0';
+ N_lanes_drvr_oe <= '0';
+ port_initalized_reg <= '0';
+ Nx_mode_active <= '0';
+ receive_lane2 <= '0';
+ force_reinit_clear <= '1'; -- = force_reinit <= '0';
+ silence_timer_en <= '1';
+ -- force_reinit
+ if force_reinit_reg = '1' then
+ mode_init_state <= SILENT;
+ -- silence_timer_done
+ elsif silence_timer_done = '1' then
+ mode_init_state <= SEEK;
+ end if;
+
+ when SEEK =>
+ lanes02_drvr_oe <= '1';
+ silence_timer_en <= '0';
+ -- (lane_sync_0 | lane_sync_2) & idle_selected
+ if (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') and idle_selected = '1' then
+ mode_init_state <= DISCOVERY;
+ end if;
+
+ when DISCOVERY =>
+ port_initalized_reg <= '0';
+ Nx_mode_active <= '0';
+ N_lanes_drvr_oe <= Nx_mode_enabled;
+ disc_tmr_en <= '1';
+ -- Nx_mode_enabled & N_lanes_ready
+ if Nx_mode_enabled = '1' and N_lanes_ready = '1' then
+
+ mode_init_state <= Nx_MODE;
+
+ -- lane_ready[0] & (force_1x_mode & (!force_laneR | force_laneR & disc_tmr_done & !lane_ready[2])
+ -- | !force_1x_mode & disc_tmr_done & !N_lanes_ready)
+ elsif lane_ready_n(0) = '1' and ((force_1x_mode = '1' and (force_laneR = '0' or (force_laneR = '1' and disc_tmr_done = '1' and lane_ready_n(2) = '0')))
+ or (force_1x_mode = '0' and disc_tmr_done = '1' and N_lanes_ready = '0')) then
+
+ mode_init_state <= x1_MODE_LANE0;
+
+ -- lane_ready[2] & (force_1x_mode & force_laneR | disc_tmr_done & !lane_ready[0]
+ -- & (force_1x_mode & !force_laneR | !force_1x_mode & !N_lanes_ready))
+ elsif lane_ready_n(2) = '1' and ((force_1x_mode = '1' and force_laneR = '1') or
+ (disc_tmr_done = '1' and lane_ready_n(0) = '0' and
+ ((force_1x_mode = '1' and force_laneR = '0') or (force_1x_mode = '0' and N_lanes_ready = '0')))) then
+
+ mode_init_state <= x1_MODE_LANE2;
+
+ ---- -- !lane_sync[0] & !lane_sync[2] | disc_tmr_done & !lane_ready[0] & !lane_ready[2]
+ ---- elsif (lane_sync_n(0) = '0' and lane_sync_n(2) = '0') or (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0') then
+ -- disc_tmr_done & !lane_ready[0] & !lane_ready[2]
+ elsif (disc_tmr_done = '1' and lane_ready_n(0) = '0' and lane_ready_n(2) = '0') then
+
+ mode_init_state <= SILENT;
+
+ end if;
+
+ when Nx_MODE =>
+ disc_tmr_en <= '0';
+ port_initalized_reg <= '1';
+ Nx_mode_active <= '1';
+ -- !N_lanes_ready & (lane_sync[0] | lane_sync[2])
+ if N_lanes_ready = '0' and (lane_sync_n(0) = '1' or lane_sync_n(2) = '1') then
+ mode_init_state <= DISCOVERY;
+ -- !N_lanes_ready & !lane_sync[0] & !lane_sync[2]
+ elsif N_lanes_ready = '0' and lane_sync_n(0) = '0' and lane_sync_n(2) = '0' then
+ mode_init_state <= SILENT;
+ end if;
+
+ when x1_MODE_LANE0 =>
+ disc_tmr_en <= '0';
+ N_lanes_drvr_oe <= '0';
+ port_initalized_reg <= '1';
+ -- !lane_sync[0]
+ if lane_sync_n(0) = '0' then
+ mode_init_state <= SILENT;
+ -- !lane_ready[0] & lane_sync[0]
+ elsif lane_ready_n(0) = '0' and lane_sync_n(0) = '1' then
+ mode_init_state <= x1_RECOVERY;
+ end if;
+
+ when x1_MODE_LANE2 =>
+ disc_tmr_en <= '0';
+ receive_lane2 <= '1';
+ N_lanes_drvr_oe <= '0';
+ port_initalized_reg <= '1';
+ -- !lane_sync[2]
+ if lane_sync_n(2) = '0' then
+ mode_init_state <= SILENT;
+ -- !lane_ready[2] & lane_sync[2]
+ elsif lane_ready_n(2) = '0' and lane_sync_n(2) = '1' then
+ mode_init_state <= x1_RECOVERY;
+ end if;
+
+ when x1_RECOVERY =>
+ port_initalized_reg <= '0';
+ disc_tmr_en <= '1';
+ -- !lane_sync[0] & !lane_sync[2] & disc_tmr_done (!!!)
+ if lane_sync_n(0) = '0' and lane_sync_n(2) = '0' and disc_tmr_done = '1' then
+
+ mode_init_state <= SILENT;
+
+ -- lane_ready[0] & !receive_lane2 & !disc_tmr_done
+ elsif lane_sync_n(0) = '1' and receive_lane2 = '0' and disc_tmr_done = '0' then
+
+ mode_init_state <= x1_MODE_LANE0;
+
+ -- lane_ready[2] & receive_lane2 & !disc_tmr_done
+ elsif lane_sync_n(2) = '1' and receive_lane2 = '1' and disc_tmr_done = '0' then
+
+ mode_init_state <= x1_MODE_LANE2;
+
+ end if;
+
+ when others =>
+ port_initalized_reg <= '0';
+ mode_init_state <= SILENT;
+
+ end case;
+
+ end if;
+
+end process;
+
+-- Sticky force_reinit set-reset register
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+ force_reinit_reg <= '0';
+ elsif rising_edge(UCLK) then
+ case force_reinit_reg is
+ when '0' =>
+ force_reinit_reg <= force_reinit or rxbuferr_reg;
+ when '1' =>
+ -- force_reinit_reg <= not(force_reinit_clear) and not(force_reinit);
+ force_reinit_reg <= not(force_reinit_clear and not(force_reinit) and not(rxbuferr_reg));
+ when others =>
+ force_reinit_reg <= '0';
+ end case;
+ end if;
+end process;
+
+-- RXBUFRST handler
+process(rst_n, UCLK)
+ begin
+ if rst_n = '0' then
+ rxbufrst_cntr <= (others => '0');
+ rxbuferr_reg <= '0';
+ RXBUFRST <= '0';
+
+ elsif rising_edge(UCLK) then
+ case rxbuferr_reg is
+ when '0' =>
+ rxbuferr_reg <= RXBUFERR;
+ RXBUFRST <= '0';
+ when '1' =>
+ if rxbufrst_cntr = "111" then
+ rxbuferr_reg <= '0';
+ rxbufrst_cntr <= (others => '0');
+ else
+ RXBUFRST <= '1';
+ rxbufrst_cntr <= rxbufrst_cntr + '1';
+ end if;
+ when others =>
+ rxbuferr_reg <= '0';
+ end case;
+ end if;
+end process;
+
+
+-- Silence Timer Process
+-- silence_timer_done: Asserted when silence_timer_en has been continuously asserted
+-- for 120 +/- 40 µs and the state machine is in the SILENT state. The assertion of
+-- silence_timer_done causes silence_timer_en to be de-asserted. When the state
+-- machine is not in the SILENT state, silence_timer_done is de-asserted.
+process(rst_n, UCLK_DV_1024)
+ begin
+ if rst_n = '0' then
+ silence_timer_done <= '0';
+ silence_timer <= (others => '0');
+ elsif rising_edge(UCLK_DV_1024) then
+
+ case silence_timer_en is
+ when '0' =>
+ silence_timer <= (others => '0');
+ silence_timer_done <= '0';
+ when '1' =>
+ if silence_timer = SILENT_ENOUGH then
+ if mode_init_state = SILENT then
+ silence_timer_done <= '1';
+ else
+ silence_timer_done <= '0';
+ end if;
+ else
+ silence_timer <= silence_timer + '1';
+ end if;
+ when others =>
+ silence_timer <= (others => '0');
+ end case;
+ end if;
+end process;
+
+-- Discovery Timer Process
+-- disc_tmr_done: Asserted when disc_tmr_en has been continuously asserted for 28 +/- 4 ms
+-- and the state machine is in the DISCOVERY or a RECOVERY state. The assertion of
+-- disc_tmr_done causes disc_tmr_en to be de-asserted. When the state machine is in
+-- a state other than the DISCOVERY or a RECOVERY state, disc_tmr_done is de-asserted.
+process(rst_n, UCLK_DV_1024)
+ begin
+ if rst_n = '0' then
+ disc_tmr_done <= '0';
+ disc_tmr <= (others => '0');
+ elsif rising_edge(UCLK_DV_1024) then
+
+ case disc_tmr_en is
+ when '0' =>
+ disc_tmr <= (others => '0');
+ disc_tmr_done <= '0';
+ when '1' =>
+ if disc_tmr = DISCOVERY_ENDS then
+ if mode_init_state = DISCOVERY or mode_init_state = x1_RECOVERY then
+ disc_tmr_done <= '1';
+ else
+ disc_tmr_done <= '0';
+ end if;
+ else
+ disc_tmr <= disc_tmr + '1';
+ end if;
+ when others =>
+ disc_tmr <= (others => '0');
+ end case;
+ end if;
+end process;
+
+ENCHANSYNC <= '0';
+
+end rtl;
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+----------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+entity pseudo_random_number_generator is
+ Generic (
+ lfsr_init : std_logic_vector(7 downto 0) := x"01"
+ );
+ Port (
+ clk : in STD_LOGIC;
+ rst_n : in STD_LOGIC;
+ -- Pseudo random number
+ q : out STD_LOGIC_VECTOR(7 downto 0)
+ );
+end pseudo_random_number_generator;
+
+architecture Behavioral of pseudo_random_number_generator is
+
+signal lfsr : std_logic_vector(7 downto 0) := x"01";
+signal q0 : std_logic;
+
+ begin
+
+q <= lfsr;
+
+-- Polynomial: x^7 + x^6 + 1
+q0 <= lfsr(7) xnor lfsr(6) xnor lfsr(0) ;
+
+process (clk, rst_n) begin
+
+ if rst_n = '0' then
+
+ lfsr <= lfsr_init; -- x"01"; --(others => '0');
+
+ elsif rising_edge(clk) then
+
+ lfsr <= lfsr(6 downto 0) & q0;
+
+ end if;
+
+end process;
+
+end Behavioral;
+
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+--
+-- File name: serdes_wrapper_v0.vhd
+-- Rev: 0.0
+-- Description: This entity instantiates 4-Lane SerDes (GTX-Quad) of Virtex-6
+--
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.rio_common.all;
+
+entity serdes_wrapper_v0 is
+ port (
+ REFCLK : in std_logic;
+ RXUSRCLK : in std_logic;
+ RXUSRCLK2 : in std_logic;
+ TXUSRCLK : in std_logic;
+ TXUSRCLK2 : in std_logic;
+ GTXRESET : in std_logic;
+ RXBUFRST : in std_logic;
+
+ -- RXN : in std_logic_vector(N-1 downto 0);
+ -- RXP : in std_logic_vector(N-1 downto 0);
+ RXN : in std_logic_vector(0 to N-1);
+ RXP : in std_logic_vector(0 to N-1);
+ TXINHIBIT_02 : in std_logic;
+ TXINHIBIT_others : in std_logic;
+ ENCHANSYNC : in std_logic;
+ TXDATA : in std_logic_vector(N*16-1 downto 0);
+ TXCHARISK : in std_logic_vector(N*2-1 downto 0);
+ -- TXN : out std_logic_vector(N-1 downto 0);
+ -- TXP : out std_logic_vector(N-1 downto 0);
+ TXN : out std_logic_vector(0 to N-1);
+ TXP : out std_logic_vector(0 to N-1);
+ PLLLKDET : out std_logic;
+ RXDATA : out std_logic_vector(N*16-1 downto 0);
+ RXCHARISK : out std_logic_vector(N*2-1 downto 0);
+ RXCHARISCOMMA : out std_logic_vector(N*2-1 downto 0);
+ RXBYTEISALIGNED : out std_logic_vector(N-1 downto 0);
+ RXBYTEREALIGN : out std_logic_vector(N-1 downto 0);
+ RXELECIDLE : out std_logic_vector(N-1 downto 0);
+ RXDISPERR : out std_logic_vector(N*2-1 downto 0);
+ RXNOTINTABLE : out std_logic_vector(N*2-1 downto 0);
+ RXBUFERR : out std_logic;
+ CHBONDDONE : out std_logic_vector(N-1 downto 0)
+ );
+end serdes_wrapper_v0;
+
+architecture struct of serdes_wrapper_v0 is
+
+ COMPONENT srio_gt_wrapper_v6_4x
+ PORT(
+ REFCLK : IN std_logic;
+ RXUSRCLK : IN std_logic;
+ RXUSRCLK2 : IN std_logic;
+ TXUSRCLK : IN std_logic;
+ TXUSRCLK2 : IN std_logic;
+ GTXRESET : IN std_logic;
+ RXBUFRST : IN std_logic;
+ RXN0 : IN std_logic;
+ RXN1 : IN std_logic;
+ RXN2 : IN std_logic;
+ RXN3 : IN std_logic;
+ RXP0 : IN std_logic;
+ RXP1 : IN std_logic;
+ RXP2 : IN std_logic;
+ RXP3 : IN std_logic;
+ TXINHIBIT_02 : IN std_logic;
+ TXINHIBIT_13 : IN std_logic;
+ ENCHANSYNC : IN std_logic;
+ TXDATA0 : IN std_logic_vector(15 downto 0);
+ TXDATA1 : IN std_logic_vector(15 downto 0);
+ TXDATA2 : IN std_logic_vector(15 downto 0);
+ TXDATA3 : IN std_logic_vector(15 downto 0);
+ TXCHARISK0 : IN std_logic_vector(1 downto 0);
+ TXCHARISK1 : IN std_logic_vector(1 downto 0);
+ TXCHARISK2 : IN std_logic_vector(1 downto 0);
+ TXCHARISK3 : IN std_logic_vector(1 downto 0);
+ TXN0 : OUT std_logic;
+ TXN1 : OUT std_logic;
+ TXN2 : OUT std_logic;
+ TXN3 : OUT std_logic;
+ TXP0 : OUT std_logic;
+ TXP1 : OUT std_logic;
+ TXP2 : OUT std_logic;
+ TXP3 : OUT std_logic;
+ PLLLKDET : OUT std_logic;
+ RXDATA0 : OUT std_logic_vector(15 downto 0);
+ RXDATA1 : OUT std_logic_vector(15 downto 0);
+ RXDATA2 : OUT std_logic_vector(15 downto 0);
+ RXDATA3 : OUT std_logic_vector(15 downto 0);
+ RXCHARISK0 : OUT std_logic_vector(1 downto 0);
+ RXCHARISK1 : OUT std_logic_vector(1 downto 0);
+ RXCHARISK2 : OUT std_logic_vector(1 downto 0);
+ RXCHARISK3 : OUT std_logic_vector(1 downto 0);
+ RXCHARISCOMMA0 : OUT std_logic_vector(1 downto 0);
+ RXCHARISCOMMA1 : OUT std_logic_vector(1 downto 0);
+ RXCHARISCOMMA2 : OUT std_logic_vector(1 downto 0);
+ RXCHARISCOMMA3 : OUT std_logic_vector(1 downto 0);
+ RXBYTEISALIGNED: OUT std_logic_vector(3 downto 0);
+ RXBYTEREALIGN : OUT std_logic_vector(3 downto 0);
+ RXELECIDLE : OUT std_logic_vector(3 downto 0);
+ RXDISPERR0 : OUT std_logic_vector(1 downto 0);
+ RXDISPERR1 : OUT std_logic_vector(1 downto 0);
+ RXDISPERR2 : OUT std_logic_vector(1 downto 0);
+ RXDISPERR3 : OUT std_logic_vector(1 downto 0);
+ RXNOTINTABLE0 : OUT std_logic_vector(1 downto 0);
+ RXNOTINTABLE1 : OUT std_logic_vector(1 downto 0);
+ RXNOTINTABLE2 : OUT std_logic_vector(1 downto 0);
+ RXNOTINTABLE3 : OUT std_logic_vector(1 downto 0);
+ RXBUFERR : OUT std_logic;
+ CHBONDDONE0 : OUT std_logic;
+ CHBONDDONE1 : OUT std_logic;
+ CHBONDDONE2 : OUT std_logic;
+ CHBONDDONE3 : OUT std_logic
+ );
+ END COMPONENT;
+
+begin
+
+ Inst_srio_gt_wrapper_v6_4x: srio_gt_wrapper_v6_4x PORT MAP(
+ REFCLK => REFCLK ,
+ RXUSRCLK => RXUSRCLK ,
+ RXUSRCLK2 => RXUSRCLK2 ,
+ TXUSRCLK => TXUSRCLK ,
+ TXUSRCLK2 => TXUSRCLK2 ,
+ GTXRESET => GTXRESET ,
+ RXBUFRST => RXBUFRST ,
+ RXN0 => RXN(0) ,
+ RXN1 => RXN(1) ,
+ RXN2 => RXN(2) ,
+ RXN3 => RXN(3) ,
+ RXP0 => RXP(0) ,
+ RXP1 => RXP(1) ,
+ RXP2 => RXP(2) ,
+ RXP3 => RXP(3) ,
+ TXINHIBIT_02 => TXINHIBIT_02 ,
+ TXINHIBIT_13 => TXINHIBIT_others ,
+ ENCHANSYNC => ENCHANSYNC ,
+ TXDATA0 => TXDATA(15 downto 0) ,
+ TXDATA1 => TXDATA(31 downto 16) ,
+ TXDATA2 => TXDATA(47 downto 32) ,
+ TXDATA3 => TXDATA(63 downto 48) ,
+ TXCHARISK0 => TXCHARISK(1 downto 0) ,
+ TXCHARISK1 => TXCHARISK(3 downto 2) ,
+ TXCHARISK2 => TXCHARISK(5 downto 4) ,
+ TXCHARISK3 => TXCHARISK(7 downto 6) ,
+ TXN0 => TXN(0) ,
+ TXN1 => TXN(1) ,
+ TXN2 => TXN(2) ,
+ TXN3 => TXN(3) ,
+ TXP0 => TXP(0) ,
+ TXP1 => TXP(1) ,
+ TXP2 => TXP(2) ,
+ TXP3 => TXP(3) ,
+ PLLLKDET => PLLLKDET ,
+ RXDATA0 => RXDATA(15 downto 0) ,
+ RXDATA1 => RXDATA(31 downto 16) ,
+ RXDATA2 => RXDATA(47 downto 32) ,
+ RXDATA3 => RXDATA(63 downto 48) ,
+ RXCHARISK0 => RXCHARISK(1 downto 0) ,
+ RXCHARISK1 => RXCHARISK(3 downto 2) ,
+ RXCHARISK2 => RXCHARISK(5 downto 4) ,
+ RXCHARISK3 => RXCHARISK(7 downto 6) ,
+ RXCHARISCOMMA0 => RXCHARISCOMMA(1 downto 0) ,
+ RXCHARISCOMMA1 => RXCHARISCOMMA(3 downto 2) ,
+ RXCHARISCOMMA2 => RXCHARISCOMMA(5 downto 4) ,
+ RXCHARISCOMMA3 => RXCHARISCOMMA(7 downto 6) ,
+ RXBYTEISALIGNED => RXBYTEISALIGNED ,
+ RXBYTEREALIGN => RXBYTEREALIGN ,
+ RXELECIDLE => RXELECIDLE ,
+ RXDISPERR0 => RXDISPERR(1 downto 0) ,
+ RXDISPERR1 => RXDISPERR(3 downto 2) ,
+ RXDISPERR2 => RXDISPERR(5 downto 4) ,
+ RXDISPERR3 => RXDISPERR(7 downto 6) ,
+ RXNOTINTABLE0 => RXNOTINTABLE(1 downto 0) ,
+ RXNOTINTABLE1 => RXNOTINTABLE(3 downto 2) ,
+ RXNOTINTABLE2 => RXNOTINTABLE(5 downto 4) ,
+ RXNOTINTABLE3 => RXNOTINTABLE(7 downto 6) ,
+ RXBUFERR => RXBUFERR ,
+ CHBONDDONE0 => CHBONDDONE(0) ,
+ CHBONDDONE1 => CHBONDDONE(1) ,
+ CHBONDDONE2 => CHBONDDONE(2) ,
+ CHBONDDONE3 => CHBONDDONE(3)
+ );
+
+end struct;
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - A. Demirezen, azdem@opencores.org
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.ALL;
+use ieee.numeric_std.ALL;
+library UNISIM;
+use UNISIM.Vcomponents.ALL;
+
+entity srio_pcs_struct is
+ port ( CHBONDDONE : in std_logic_vector (3 downto 0);
+ force_reinit_i : in std_logic;
+ inboundRead_i : in std_logic;
+ outboundSymbol_i : in std_logic_vector (33 downto 0);
+ outboundWrite_i : in std_logic;
+ PLLLKDET : in std_logic;
+ rio_clk : in std_logic;
+ rst_n : in std_logic;
+ RXBUFERR : in std_logic;
+ RXBYTEISALIGNED : in std_logic_vector (3 downto 0);
+ RXBYTEREALIGN : in std_logic_vector (3 downto 0);
+ RXCAHRISCOMMA : in std_logic_vector (7 downto 0);
+ RXCAHRISK : in std_logic_vector (7 downto 0);
+ RXDATA : in std_logic_vector (63 downto 0);
+ RXDISPERR : in std_logic_vector (7 downto 0);
+ RXELECIDLE : in std_logic_vector (3 downto 0);
+ RXNOTINTABLE : in std_logic_vector (7 downto 0);
+ UCLK : in std_logic;
+ UCLK_DV4 : in std_logic;
+ UCLK_DV1024 : in std_logic;
+ UCLK_or_DV4 : in std_logic;
+ UCLK_x2 : in std_logic;
+ UCLK_x2_DV2 : in std_logic;
+ ENCHANSYNC : out std_logic;
+ inboundEmpty_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector (33 downto 0);
+ lane_sync_o : out std_logic_vector (3 downto 0);
+ mode_sel_o : out std_logic;
+ mode_0_lane_sel_o : out std_logic;
+ outboundFull_o : out std_logic;
+ port_initialized_o : out std_logic;
+ RXBUFRST : out std_logic;
+ TXCAHRISK : out std_logic_vector (7 downto 0);
+ TXDATA : out std_logic_vector (63 downto 0);
+ TXINHIBIT_others : out std_logic;
+ TXINHIBIT_02 : out std_logic);
+end srio_pcs_struct;
+
+architecture BEHAVIORAL of srio_pcs_struct is
+ signal ccs_timer_rst : std_logic;
+ signal RXCAHRISvalid : std_logic_vector (7 downto 0);
+ signal send_A : std_logic_vector (1 downto 0);
+ signal send_ccs : std_logic;
+ signal send_idle : std_logic_vector (1 downto 0);
+ signal send_K : std_logic_vector (1 downto 0);
+ signal send_R : std_logic_vector (1 downto 0);
+ signal mode_0_lane_sel_o_DUMMY : std_logic;
+ signal TXINHIBIT_02_DUMMY : std_logic;
+ signal mode_sel_o_DUMMY : std_logic;
+ signal port_initialized_o_DUMMY : std_logic;
+ signal TXINHIBIT_others_DUMMY : std_logic;
+ component ccs_timer
+ port ( rst_n : in std_logic;
+ ccs_timer_rst : in std_logic;
+ send_ccs : out std_logic;
+ UCLK : in std_logic);
+ end component;
+
+ component idle_generator_dual
+ port ( UCLK : in std_logic;
+ rst_n : in std_logic;
+ send_K : out std_logic_vector (1 downto 0);
+ send_A : out std_logic_vector (1 downto 0);
+ send_R : out std_logic_vector (1 downto 0);
+ send_idle : in std_logic_vector (1 downto 0));
+ end component;
+
+ component port_init_fsms
+ port ( rst_n : in std_logic;
+ UCLK_x2 : in std_logic;
+ UCLK : in std_logic;
+ UCLK_DV4 : in std_logic;
+ UCLK_DV_1024 : in std_logic;
+ force_reinit : in std_logic;
+ PLLLKDET : in std_logic;
+ RXBUFERR : in std_logic;
+ RXDATA : in std_logic_vector (63 downto 0);
+ RXCHARISK : in std_logic_vector (7 downto 0);
+ RXCHARISCOMMA : in std_logic_vector (7 downto 0);
+ RXBYTEISALIGNED : in std_logic_vector (3 downto 0);
+ RXBYTEREALIGN : in std_logic_vector (3 downto 0);
+ RXELECIDLE : in std_logic_vector (3 downto 0);
+ RXDISPERR : in std_logic_vector (7 downto 0);
+ RXNOTINTABLE : in std_logic_vector (7 downto 0);
+ CHBONDDONE : in std_logic_vector (3 downto 0);
+ mode_sel : out std_logic;
+ port_initalized : out std_logic;
+ TXINHIBIT_02 : out std_logic;
+ TXINHIBIT_others : out std_logic;
+ ENCHANSYNC : out std_logic;
+ RXBUFRST : out std_logic;
+ lane_sync : out std_logic_vector (3 downto 0);
+ mode_0_lane_sel : out std_logic;
+ RXCHARISvalid : out std_logic_vector (7 downto 0));
+ end component;
+
+ component pcs_rx_controller
+ port ( rst_n : in std_logic;
+ rio_clk : in std_logic;
+ UCLK_x2 : in std_logic;
+ UCLK : in std_logic;
+ UCLK_x2_DV2 : in std_logic;
+ inboundRead_i : in std_logic;
+ port_initalized_i : in std_logic;
+ mode_sel_i : in std_logic;
+ mode_0_lane_sel_i : in std_logic;
+ RXDATA_i : in std_logic_vector (63 downto 0);
+ RXCHARISK_i : in std_logic_vector (7 downto 0);
+ RXCHARISvalid_i : in std_logic_vector (7 downto 0);
+ inboundEmpty_o : out std_logic;
+ inboundSymbol_o : out std_logic_vector (33 downto 0);
+ UCLK_or_DV4 : in std_logic);
+ end component;
+
+ component pcs_tx_controller
+ port ( rst_n : in std_logic;
+ rio_clk : in std_logic;
+ UCLK_x2 : in std_logic;
+ UCLK : in std_logic;
+ UCLK_x2_DV2 : in std_logic;
+ UCLK_or_DV4 : in std_logic;
+ outboundWrite_i : in std_logic;
+ send_ccs_i : in std_logic;
+ TXINHIBIT_02 : in std_logic;
+ TXINHIBIT_others : in std_logic;
+ port_initalized_i : in std_logic;
+ mode_sel_i : in std_logic;
+ mode_0_lane_sel_i : in std_logic;
+ outboundSymbol_i : in std_logic_vector (33 downto 0);
+ send_K_i : in std_logic_vector (1 downto 0);
+ send_A_i : in std_logic_vector (1 downto 0);
+ send_R_i : in std_logic_vector (1 downto 0);
+ outboundFull_o : out std_logic;
+ ccs_timer_rst_o : out std_logic;
+ TXDATA_o : out std_logic_vector (63 downto 0);
+ TXCHARISK_o : out std_logic_vector (7 downto 0);
+ send_idle_o : out std_logic_vector (1 downto 0));
+ end component;
+
+begin
+ mode_sel_o <= mode_sel_o_DUMMY;
+ mode_0_lane_sel_o <= mode_0_lane_sel_o_DUMMY;
+ port_initialized_o <= port_initialized_o_DUMMY;
+ TXINHIBIT_others <= TXINHIBIT_others_DUMMY;
+ TXINHIBIT_02 <= TXINHIBIT_02_DUMMY;
+ ccs_timer_inst : ccs_timer
+ port map (ccs_timer_rst=>ccs_timer_rst,
+ rst_n=>rst_n,
+ UCLK=>UCLK,
+ send_ccs=>send_ccs);
+
+ dual_idle_generator : idle_generator_dual
+ port map (rst_n=>rst_n,
+ send_idle(1 downto 0)=>send_idle(1 downto 0),
+ UCLK=>UCLK,
+ send_A(1 downto 0)=>send_A(1 downto 0),
+ send_K(1 downto 0)=>send_K(1 downto 0),
+ send_R(1 downto 0)=>send_R(1 downto 0));
+
+ port_init_fsms_inst : port_init_fsms
+ port map (CHBONDDONE(3 downto 0)=>CHBONDDONE(3 downto 0),
+ force_reinit=>force_reinit_i,
+ PLLLKDET=>PLLLKDET,
+ rst_n=>rst_n,
+ RXBUFERR=>RXBUFERR,
+ RXBYTEISALIGNED(3 downto 0)=>RXBYTEISALIGNED(3 downto 0),
+ RXBYTEREALIGN(3 downto 0)=>RXBYTEREALIGN(3 downto 0),
+ RXCHARISCOMMA(7 downto 0)=>RXCAHRISCOMMA(7 downto 0),
+ RXCHARISK(7 downto 0)=>RXCAHRISK(7 downto 0),
+ RXDATA(63 downto 0)=>RXDATA(63 downto 0),
+ RXDISPERR(7 downto 0)=>RXDISPERR(7 downto 0),
+ RXELECIDLE(3 downto 0)=>RXELECIDLE(3 downto 0),
+ RXNOTINTABLE(7 downto 0)=>RXNOTINTABLE(7 downto 0),
+ UCLK=>UCLK,
+ UCLK_DV_1024=>UCLK_DV1024,
+ UCLK_DV4=>UCLK_DV4,
+ UCLK_x2=>UCLK_x2,
+ ENCHANSYNC=>ENCHANSYNC,
+ lane_sync(3 downto 0)=>lane_sync_o(3 downto 0),
+ mode_sel=>mode_sel_o_DUMMY,
+ mode_0_lane_sel=>mode_0_lane_sel_o_DUMMY,
+ port_initalized=>port_initialized_o_DUMMY,
+ RXBUFRST=>RXBUFRST,
+ RXCHARISvalid(7 downto 0)=>RXCAHRISvalid(7 downto 0),
+ TXINHIBIT_others=>TXINHIBIT_others_DUMMY,
+ TXINHIBIT_02=>TXINHIBIT_02_DUMMY);
+
+ rx_controller_inst : pcs_rx_controller
+ port map (inboundRead_i=>inboundRead_i,
+ mode_sel_i=>mode_sel_o_DUMMY,
+ mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY,
+ port_initalized_i=>port_initialized_o_DUMMY,
+ rio_clk=>rio_clk,
+ rst_n=>rst_n,
+ RXCHARISK_i(7 downto 0)=>RXCAHRISK(7 downto 0),
+ RXCHARISvalid_i(7 downto 0)=>RXCAHRISvalid(7 downto 0),
+ RXDATA_i(63 downto 0)=>RXDATA(63 downto 0),
+ UCLK=>UCLK,
+ UCLK_or_DV4=>UCLK_or_DV4,
+ UCLK_x2=>UCLK_x2,
+ UCLK_x2_DV2=>UCLK_x2_DV2,
+ inboundEmpty_o=>inboundEmpty_o,
+ inboundSymbol_o(33 downto 0)=>inboundSymbol_o(33 downto 0));
+
+ tx_controller_inst : pcs_tx_controller
+ port map (mode_sel_i=>mode_sel_o_DUMMY,
+ mode_0_lane_sel_i=>mode_0_lane_sel_o_DUMMY,
+ outboundSymbol_i(33 downto 0)=>outboundSymbol_i(33 downto 0),
+ outboundWrite_i=>outboundWrite_i,
+ port_initalized_i=>port_initialized_o_DUMMY,
+ rio_clk=>rio_clk,
+ rst_n=>rst_n,
+ send_A_i(1 downto 0)=>send_A(1 downto 0),
+ send_ccs_i=>send_ccs,
+ send_K_i(1 downto 0)=>send_K(1 downto 0),
+ send_R_i(1 downto 0)=>send_R(1 downto 0),
+ TXINHIBIT_others=>TXINHIBIT_others_DUMMY,
+ TXINHIBIT_02=>TXINHIBIT_02_DUMMY,
+ UCLK=>UCLK,
+ UCLK_or_DV4=>UCLK_or_DV4,
+ UCLK_x2=>UCLK_x2,
+ UCLK_x2_DV2=>UCLK_x2_DV2,
+ ccs_timer_rst_o=>ccs_timer_rst,
+ outboundFull_o=>outboundFull_o,
+ send_idle_o(1 downto 0)=>send_idle(1 downto 0),
+ TXCHARISK_o(7 downto 0)=>TXCAHRISK(7 downto 0),
+ TXDATA_o(63 downto 0)=>TXDATA(63 downto 0));
+
+end BEHAVIORAL;
+
+
Index: tags/1.0.2-release/rtl/vhdl/RioWbBridge.vhd
===================================================================
--- tags/1.0.2-release/rtl/vhdl/RioWbBridge.vhd (nonexistent)
+++ tags/1.0.2-release/rtl/vhdl/RioWbBridge.vhd (revision 50)
@@ -0,0 +1,935 @@
+-------------------------------------------------------------------------------
+--
+-- RapidIO IP Library Core
+--
+-- This file is part of the RapidIO IP library project
+-- http://www.opencores.org/cores/rio/
+--
+-- Description
+-- Containing a bridge between a RapidIO network and a Wishbone bus. Packets
+-- NWRITE and NREAD are currently supported.
+--
+-- To Do:
+-- -
+--
+-- Author(s):
+-- - Nader Kardouni, nader.kardouni@se.transport.bombardier.com
+--
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Authors and OPENCORES.ORG
+--
+-- This source file may be used and distributed without
+-- restriction provided that this copyright statement is not
+-- removed from the file and that any derivative work contains
+-- the original copyright notice and the associated disclaimer.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source 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 Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.opencores.org/lgpl.shtml
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.numeric_std.ALL;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use work.rio_common.all;
+
+-------------------------------------------------------------------------------
+-- entity for RioWbBridge.
+-------------------------------------------------------------------------------
+Entity RioWbBridge is
+ generic(
+ DEVICE_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ DEVICE_REV : std_logic_vector(31 downto 0);
+ ASSY_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_VENDOR_IDENTITY : std_logic_vector(15 downto 0);
+ ASSY_REV : std_logic_vector(15 downto 0);
+ DEFAULT_BASE_DEVICE_ID : std_logic_vector(15 downto 0) := x"ffff");
+ port(
+ clk : in std_logic; -- Main clock 25MHz
+ areset_n : in std_logic; -- Asynchronous reset, active low
+
+ readFrameEmpty_i : in std_logic;
+ readFrame_o : out std_logic;
+ readContent_o : out std_logic;
+ readContentEnd_i : in std_logic;
+ readContentData_i : in std_logic_vector(31 downto 0);
+
+ writeFrameFull_i : in std_logic;
+ writeFrame_o : out std_logic;
+ writeFrameAbort_o : out std_logic;
+ writeContent_o : out std_logic;
+ writeContentData_o : out std_logic_vector(31 downto 0);
+
+ -- interface to the peripherals module
+ wbStb_o : out std_logic; -- strob signal, active high
+ wbWe_o : out std_logic; -- write signal, active high
+ wbData_o : out std_logic_vector(7 downto 0); -- master data bus
+ wbAdr_o : out std_logic_vector(25 downto 0); -- master address bus
+ wbErr_i : in std_logic; -- error signal, high active
+ wbAck_i : in std_logic; -- slave acknowledge
+ wbData_i : in std_logic_vector(7 downto 0) -- slave data bus
+ );
+end;
+
+-------------------------------------------------------------------------------
+-- Architecture for RioWbBridge.
+-------------------------------------------------------------------------------
+architecture rtl of RioWbBridge is
+
+ component Crc16CITT is
+ port(
+ d_i : in std_logic_vector(15 downto 0);
+ crc_i : in std_logic_vector(15 downto 0);
+ crc_o : out std_logic_vector(15 downto 0));
+ end component;
+
+ constant RST_LVL : std_logic := '0';
+ constant BERR_UNKNOWN_DATA : std_logic_vector(7 downto 0) := X"08"; -- not valid data
+ constant BERR_FRAME_SIZE : std_logic_vector(7 downto 0) := X"81"; -- Frame code size error
+ constant BERR_FRAME_CODE : std_logic_vector(7 downto 0) := X"80"; -- Frame code type error
+ constant BERR_NOT_RESPONSE : std_logic_vector(7 downto 0) := X"86"; -- Not response from the device
+
+ type state_type_RioBrige is (IDLE, WAIT_HEADER_0, HEADER_0, HEADER_1, CHECK_OPERATION,
+ READ_ADDRESS, READ_FROM_FIFO, CHECK_ERROR, WRITE_DATA,
+ WRITE_TO_WB, WAIT_IDLE, SEND_DONE_0, SEND_DONE_1,
+ SEND_DONE_2, READ_FROM_WB, APPEND_CRC,
+ SEND_TO_FIFO, SEND_ERROR, SEND_FRAME, APPEND_CRC_AND_SEND,
+ SEND_MAINTENANCE_READ_RESPONSE_0, SEND_MAINTENANCE_READ_RESPONSE_1,
+ SEND_MAINTENANCE_WRITE_RESPONSE_0, SEND_MAINTENANCE_WRITE_RESPONSE_1);
+ signal stateRB, nextStateRB : state_type_RioBrige;
+ type byteArray8 is array (0 to 7) of std_logic_vector(7 downto 0);
+ signal dataLane : byteArray8;
+-- type byteArray4 is array (0 to 3) of std_logic_vector(7 downto 0);
+-- signal dataLaneS : byteArray4;
+ signal pos, byteOffset : integer range 0 to 7;
+ signal numberOfByte, byteCnt, headLen : integer range 0 to 256;
+ signal endianMsb, reserved, ready : std_logic;
+ signal start : std_logic;
+ signal wdptr : std_logic;
+ signal wbStb : std_logic;
+ signal xamsbs : std_logic_vector(1 downto 0);
+ signal ftype : std_logic_vector(3 downto 0);
+ signal ttype : std_logic_vector(3 downto 0);
+ signal size : std_logic_vector(3 downto 0);
+ signal tid : std_logic_vector(7 downto 0);
+ signal tt : std_logic_vector(1 downto 0);
+ signal errorCode : std_logic_vector(7 downto 0);
+ signal sourceId : std_logic_vector(15 downto 0);
+ signal destinationId : std_logic_vector(15 downto 0);
+ signal writeContentData : std_logic_vector(31 downto 0);
+ signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0);
+ signal tempAddr : std_logic_vector(25 downto 0);
+ signal timeOutCnt : std_logic_vector(14 downto 0);
+
+ -- Configuration memory signal declaration.
+ signal configEnable : std_logic;
+ signal configWrite : std_logic;
+ signal configAddress : std_logic_vector(23 downto 0);
+ signal configDataWrite : std_logic_vector(31 downto 0);
+ signal configDataRead : std_logic_vector(31 downto 0);
+ signal componentTag : std_logic_vector(31 downto 0);
+ signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID;
+ signal hostBaseDeviceIdLocked : std_logic;
+ signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1');
+
+begin
+ wbStb_o <= wbStb;
+ writeContentData_o <= writeContentData;
+
+ Crc16High: Crc16CITT
+ port map(
+ d_i=>writeContentData(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
+ Crc16Low: Crc16CITT
+ port map(
+ d_i=>writeContentData(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
+
+
+
+ -----------------------------------------------------------------------------
+ -- wbInterfaceCtrl
+ -- This process handle the Wishbone interface to the RioWbBridge module.
+ -----------------------------------------------------------------------------
+ wbInterfaceCtrl: process(clk, areset_n)
+ variable Temp : std_logic_vector(2 downto 0);
+ begin
+ if areset_n = RST_LVL then
+ start <= '0';
+ wdptr <= '0';
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteCnt <= 0;
+ headLen <= 0;
+ byteOffset <= 0;
+ readFrame_o <= '0';
+ readContent_o <= '0';
+ writeFrame_o <= '0';
+ writeContent_o <= '0';
+ writeFrameAbort_o <= '0';
+ configWrite <= '0';
+ configEnable <= '0';
+ ready <= '0';
+ endianMsb <= '0';
+ stateRB <= IDLE;
+ nextStateRB <= IDLE;
+ tt <= (others => '0');
+ tid <= (others => '0');
+ size <= (others => '0');
+ ttype <= (others => '0');
+ ftype <= (others => '0');
+ xamsbs <= (others => '0');
+ sourceId <= (others => '0');
+ configDataWrite <= (others => '0');
+ destinationId <= (others => '0');
+ errorCode <= (others => '0');
+ tempAddr <= (others => '0');
+ wbAdr_o <= (others => '0');
+ wbData_o <= (others => '0');
+ writeContentData <= (others => '0');
+ dataLane <= (others =>(others => '0'));
+-- dataLaneS <= (others =>(others => '0'));
+ crc16Current <= (others => '0');
+ timeOutCnt <= (others => '0');
+ Temp := (others => '0');
+ elsif clk'event and clk ='1' then
+
+ case stateRB is
+ when IDLE =>
+ if (readFrameEmpty_i = '0') and (writeFrameFull_i = '0') then
+ readContent_o <= '1';
+ byteCnt <= 0;
+ ready <= '0';
+ endianMsb <= '1';
+ timeOutCnt <= (others => '0');
+ crc16Current <= (others => '1');
+ stateRB <= WAIT_HEADER_0;
+ else
+ start <= '0';
+ readFrame_o <= '0';
+ readContent_o <= '0';
+ writeFrame_o <= '0';
+ writeContent_o <= '0';
+ writeFrameAbort_o <= '0';
+ errorCode <= (others => '0');
+ writeContentData <= (others => '0');
+ dataLane <= (others =>(others => '0'));
+-- dataLaneS <= (others =>(others => '0'));
+ Temp := (others => '0');
+ end if;
+
+ when WAIT_HEADER_0 =>
+ stateRB <= HEADER_0;
+
+ when HEADER_0 =>
+ readContent_o <= '1'; -- read the header (frame 0)
+ tt <= readContentData_i(21 downto 20);
+ ftype <= readContentData_i(19 downto 16);
+ destinationId <= readContentData_i(15 downto 0);
+ stateRB <= HEADER_1;
+
+ when HEADER_1 => -- read the header (frame 1)
+ readContent_o <= '1';
+ ttype <= readContentData_i(15 downto 12);
+ size <= readContentData_i(11 downto 8);
+ tid <= readContentData_i(7 downto 0);
+ sourceId <= readContentData_i(31 downto 16);
+ stateRB <= READ_ADDRESS;
+
+ when READ_ADDRESS =>
+ readContent_o <= '0';
+ wdptr <= readContentData_i(2);
+ xamsbs <= readContentData_i(1 downto 0);
+ tempAddr <= readContentData_i(25 downto 3) & "000"; -- Wishbone address bus is 26 bits width
+ configAddress <= readContentData_i(23 downto 0); -- this line is in case of maintenance pakage (config-offset(21-bits)+wdptr(1-bit)+rsv(2-bits))
+ stateRB <= CHECK_ERROR;
+
+ when CHECK_ERROR =>
+ byteOffset <= pos; -- first byte position in the first payload
+ tempAddr <= tempAddr + pos; -- first address
+ if readContentEnd_i = '1' then -- check if data not valid i the switch buffer
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_UNKNOWN_DATA; -- not valid data
+ stateRB <= SEND_ERROR;
+
+ -- check if error in the frame size for write pakage
+ elsif (reserved = '1') and (ftype = FTYPE_WRITE_CLASS) then
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_SIZE; -- Frame code size error
+ stateRB <= SEND_ERROR;
+
+ -- type 5 pakage formate, NWRITE transaction (write to peripherals) read payload from the buffer
+ elsif (ftype = FTYPE_WRITE_CLASS) and (ttype = "0100") and (tt = "01") then
+ readContent_o <= '1';
+ stateRB <= READ_FROM_FIFO; -- read the payload
+ nextStateRB <= SEND_ERROR; -- this is in case not valid data in switch buffer
+ headLen <= 12;
+
+ -- Type 2 pakage formate, NREAD transaction, (read from peripherals) write payload to the buffer
+ elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = "0100") and (tt = "01") then
+ writeContent_o <= '1'; -- write the header-0 of the Read Response pakage
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address
+ writeContentData(19 downto 16) <= "1101"; -- Response pakage type 13, ftype Response
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_DONE_0; --
+ headLen <= 8;
+
+ -- Type 8 pakage formate, maintenance Read request
+ elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_READ_REQUEST) and (tt = "01") then
+ configWrite <= '0'; -- read config operation
+ configEnable <= '1'; -- enable signal to the memoryConfig process
+ writeContent_o <= '1';
+ -- write the header-0 of the Read Response pakage
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
+ writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_MAINTENANCE_READ_RESPONSE_0;
+
+ -- Type 8 pakage formate, maintenance Write request
+ elsif (ftype = FTYPE_MAINTENANCE_CLASS) and (ttype = TTYPE_MAINTENANCE_WRITE_REQUEST) and (tt = "01") then
+ configWrite <= '1'; -- write config operation
+ writeContent_o <= '1'; -- write the header-0
+ writeContentData(15 downto 0) <= sourceId; -- write to the source address, this is a response pakage
+ writeContentData(19 downto 16) <= FTYPE_MAINTENANCE_CLASS; -- ftype, maintenance
+ writeContentData(21 downto 20) <= "01"; -- tt
+ writeContentData(31 downto 22) <= "0000000000"; -- acckId, vc, cfr, prio
+ stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_0;
+
+ -- Error: unexpected ftype or ttype
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_CODE;
+ stateRB <= SEND_ERROR; -- next state after the dataLane is stored in the switch buffer
+ end if;
+
+ when SEND_MAINTENANCE_READ_RESPONSE_0 =>
+ byteCnt <= 0;
+ configEnable <= '0'; -- disable signal to the memoryConfig process
+ -- write the header-1 of the Read Response pakage
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_READ_RESPONSE; -- transaction type, Maintenance Read Response
+ writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_MAINTENANCE_READ_RESPONSE_1;
+
+ when SEND_MAINTENANCE_READ_RESPONSE_1 =>
+ byteCnt <= byteCnt + 1; -- using byteCnt as a counter
+ if byteCnt = 0 then
+ writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteCnt = 1 then
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ writeContentData <= configDataRead; -- write payload-0 with data if wdptr='0'
+ else
+ writeContentData <= (others => '0'); -- write zeros
+ end if;
+ crc16Current <= crc16Next; -- third frame's CRC
+ elsif byteCnt = 2 then
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ writeContentData <= (others => '0'); -- write zeros
+ else
+ writeContentData <= configDataRead; -- write payload-1 with data if wdptr='1'
+ end if;
+ crc16Current <= crc16Next; -- forth frame's CRC
+ elsif byteCnt = 3 then
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ else
+ writeContent_o <= '0';
+ stateRB <= SEND_FRAME;
+ end if;
+
+ when SEND_MAINTENANCE_WRITE_RESPONSE_0 =>
+ byteCnt <= 0;
+ readContent_o <= '1'; -- read the config offset
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ configDataWrite <= readContentData_i; -- copy payload-0 if wdptr='0'
+ else
+ configDataWrite <= configDataWrite; -- do nothing
+ end if;
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= TTYPE_MAINTENANCE_WRITE_RESPONSE; -- transaction type, Maintenance Write Response
+ writeContentData(31 downto 16) <= baseDeviceId; -- destination address, because this is a response pakage
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_MAINTENANCE_WRITE_RESPONSE_1;
+
+ when SEND_MAINTENANCE_WRITE_RESPONSE_1 =>
+ byteCnt <= byteCnt + 1; -- using byteCnt as a counter
+ if byteCnt = 0 then
+ writeContentData <= X"FF" & X"000000"; -- write the filed with HOP + reserved
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteCnt = 1 then
+ configEnable <= '1'; -- enable signal to the memoryConfig process
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ if configAddress(2) = '0' then -- check the wdptr bit in the config offset field
+ configDataWrite <= configDataWrite; -- do nothing
+ else
+ configDataWrite <= readContentData_i; -- copy payload-1 if wdptr='1'
+ end if;
+ else
+ configEnable <= '0'; -- disable signal to the memoryConfig process
+ readContent_o <= '0'; -- at this point even the frame's CRC is read from the buffer
+ writeContent_o <= '0';
+ stateRB <= SEND_FRAME;
+ end if;
+
+ when SEND_DONE_0 =>
+ writeContent_o <= '1';
+ writeContentData(7 downto 0) <= tid;
+ writeContentData(11 downto 8) <= "0000"; -- size/status
+ writeContentData(15 downto 12) <= "1000"; -- ttype
+ writeContentData(31 downto 16) <= baseDeviceId;
+ crc16Current <= crc16Next; -- first frame's CRC
+ stateRB <= SEND_DONE_1;
+
+ when SEND_DONE_1 =>
+ byteCnt <= 0;
+ dataLane <= (others =>(others => '0'));
+ writeContent_o <= '0'; -- this line is to make sure that the CRC is complete read
+ crc16Current <= crc16Next; -- second frame's CRC
+ wbAdr_o <= tempAddr;
+ tempAddr <= tempAddr + 1;
+ wbStb <= '1';
+ wbWe_o <= '0';
+ byteOffset <= pos;
+ stateRB <= READ_FROM_WB;
+
+ when READ_FROM_WB =>
+ if wbAck_i = '1' then
+ timeOutCnt <= (others => '0'); -- reset the time out conter
+ if wbErr_i = '0' then -- check if no error occur
+ if (byteCnt < numberOfByte - 1) then -- check if reach the last data byte
+ byteCnt <= byteCnt + 1;
+ if (byteCnt + headLen = 80) then -- when current position in payload is a CRC position
+ dataLane(0) <= crc16Current(15 downto 8);
+ dataLane(1) <= crc16Current(7 downto 0);
+ dataLane(2) <= wbData_i;
+ byteOffset <= 3;
+ elsif byteOffset < 7 then
+ dataLane(byteOffset) <= wbData_i;
+ byteOffset <= byteOffset + 1;
+ else -- dataLane vector is ready to send to fifo
+ dataLane(7) <= wbData_i;
+ byteOffset <= 0; -- Here, sets byteOffset for other response
+ stateRB <= SEND_TO_FIFO;
+ nextStateRB <= READ_FROM_WB; --
+ end if;
+ else -- get last data from Wishbone
+ wbStb <= '0';
+ byteCnt <= 0; -- Here, using byteCnt and reset it for other response
+ dataLane(byteOffset) <= wbData_i;
+ stateRB <= APPEND_CRC_AND_SEND;
+ if byteOffset < 7 then -- checking for CRC appending position
+ byteOffset <= byteOffset + 1;
+ else
+ byteOffset <= 0;
+ end if;
+ end if;
+
+ -- when Wishbone error occur
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= wbData_i;
+ stateRB <= SEND_ERROR;
+ end if;
+ else -- when no acknowledge received
+ if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_NOT_RESPONSE;
+ stateRB <= SEND_ERROR;
+ else
+ timeOutCnt <= timeOutCnt + 1;
+ end if;
+ end if;
+
+ -- appending CRC and write to the fifo when frame is shorter then 80 bytes
+ when APPEND_CRC_AND_SEND =>
+ writeContent_o <= '0';
+ byteCnt <= byteCnt + 1;
+ -- check if frame is shorter than 80 bytes
+ if (numberOfByte < 65) then
+ -- Yes, frame is shorter then 80 bytes
+ if byteCnt = 0 then
+ -- first write the current double word to the fifo
+ -- then put the CRC in the next double word
+ byteOffset <= 0;
+ stateRB <= SEND_TO_FIFO;
+ nextStateRB <= APPEND_CRC_AND_SEND;
+ elsif byteCnt = 1 then
+ -- append the CRC
+ writeContent_o <= '1';
+ writeContentData <= crc16Current & X"0000";
+ else
+ stateRB <= SEND_FRAME; -- store in the switch buffer
+ end if;
+ else
+ --No, appending CRC and write to the fifo when frame is longer then 80 bytes
+ if byteCnt = 0 then
+ -- check if the last byte was placed in the second half of the double word,
+ -- in that case write the first word to the fifo.
+ writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
+ elsif byteCnt = 1 then
+ crc16Current <= crc16Temp; -- calcylate the crc for the 16 most significant bits
+ elsif byteCnt = 2 then
+ writeContent_o <= '1';
+ writeContentData <= dataLane(0) & dataLane(1) & crc16Current;
+ else
+ stateRB <= SEND_FRAME; -- store in the switch buffer
+ end if;
+ end if;
+
+
+ when SEND_TO_FIFO =>
+ if byteOffset = 0 then -- using byteOffset as a counter
+ byteOffset <= 1;
+ writeContent_o <= '1';
+ writeContentData <= dataLane(0) & dataLane(1) & dataLane(2) & dataLane(3);
+ elsif byteOffset = 1 then -- using byteOffset as a counter
+ byteOffset <= 2;
+ writeContent_o <= '0';
+ crc16Current <= crc16Next; -- calcylate the crc
+ elsif byteOffset = 2 then
+ byteOffset <= 3;
+ writeContent_o <= '1';
+ writeContentData <= dataLane(4) & dataLane(5) & dataLane(6) & dataLane(7);
+ elsif byteOffset = 3 then
+ crc16Current <= crc16Next; -- calcylate the crc
+ writeContent_o <= '0';
+ byteOffset <= 0;
+ stateRB <= nextStateRB;
+ dataLane <= (others =>(others => '0'));
+ end if;
+
+ when READ_FROM_FIFO =>
+ if (endianMsb = '1') then
+ if (readContentEnd_i = '0') then
+ endianMsb <= '0';
+ dataLane(0 to 3) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
+ readContentData_i(15 downto 8), readContentData_i(7 downto 0));
+ else
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ readContent_o <= '0';
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_FRAME_SIZE;
+ stateRB <= SEND_ERROR;
+-- stateRB <= IDLE;
+ end if;
+ else
+ endianMsb <= '1';
+ readContent_o <= '0';
+ dataLane(4 to 7) <= (readContentData_i(31 downto 24), readContentData_i(23 downto 16),
+ readContentData_i(15 downto 8), readContentData_i(7 downto 0));
+ if ready = '1' then
+ stateRB <= nextStateRB;
+ else
+ stateRB <= WRITE_TO_WB;
+ end if;
+ end if;
+
+ when WRITE_TO_WB =>
+ if wbStb = '0' then
+ wbStb <= '1';
+ wbWe_o <= '1';
+ byteCnt <= 1;
+ byteOffset <= byteOffset + 1; -- increase number of counted byte
+ tempAddr <= tempAddr + 1; -- increase the memory sddress address
+ wbAdr_o <= tempAddr;
+ wbData_o <= dataLane(byteOffset);
+ else
+ if wbAck_i = '1' then
+ timeOutCnt <= (others => '0'); -- reset the time out conter
+ if wbErr_i = '0' then -- check the peripherals error signal
+ if byteCnt < numberOfByte then
+ tempAddr <= tempAddr + 1; -- increase the memory sddress address
+ wbAdr_o <= tempAddr;
+ wbData_o <= dataLane(byteOffset);
+ byteCnt <= byteCnt + 1; -- increase number of counted byte
+ if byteOffset < 7 then
+ if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
+ byteOffset <= byteOffset + 3;
+ else
+ byteOffset <= byteOffset + 1;
+ end if;
+ else
+ if (byteCnt + headLen = 79) then -- check for the CRC-byte position 80 in the frame
+ byteOffset <= 2;
+ else
+ byteOffset <= 0;
+ end if;
+ if byteCnt < numberOfByte - 1 then
+ readContent_o <= '1';
+ stateRB <= READ_FROM_FIFO;
+ end if;
+ end if;
+ else -- no more data to send to the peripherals
+ wbStb <= '0';
+ wbWe_o <= '0';
+ ready <= '1';
+ stateRB <= SEND_FRAME;
+ end if;
+ else -- if the peripheral generates an error, send an error Response
+ wbStb <= '0';
+ wbWe_o <= '0';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= wbData_i;
+ stateRB <= SEND_ERROR;
+ end if;
+ else
+-- if readContentEnd_i = '1' then -- when unvalid data in the switch buffer
+-- wbStb <= '0';
+-- wbWe_o <= '0';
+-- readFrame_o <= '1';
+-- byteOffset <= 0;
+-- writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+-- errorCode <= BERR_FRAME_SIZE; -- more data content is expected, Frame size error
+-- stateRB <= SEND_ERROR;
+-- else
+ if timeOutCnt(13) = '1' then -- when waiting more than 1 ms for response from the device
+ wbStb <= '0';
+ wbWe_o <= '0';
+ readFrame_o <= '1';
+ byteOffset <= 0;
+ writeFrameAbort_o <= '1'; -- over write the frame with an error frame
+ errorCode <= BERR_NOT_RESPONSE;
+ stateRB <= SEND_ERROR;
+ else
+ timeOutCnt <= timeOutCnt + 1;
+ end if;
+-- end if;
+ end if;
+ end if;
+
+ when SEND_ERROR => -- Generate a Response Class, an error pakage ftype=13, ttype=8, status="1111"
+ readFrame_o <= '0';
+ writeFrameAbort_o <= '0';
+ byteOffset <= byteOffset + 1;
+ if byteOffset = 0 then
+ writeContent_o <= '1'; -- start write to the buffer
+ crc16Current <= (others => '1');
+ writeContentData <= "00000000" & "00" & "01" & "1101" & sourceId;
+ elsif byteOffset = 1 then
+ writeContentData <= baseDeviceId & "1000" & "1111" & tid;
+ crc16Current <= crc16Next; -- first frame's CRC
+ elsif byteOffset = 2 then
+ writeContentData <= errorCode & x"000000";
+ crc16Current <= crc16Next; -- second frame's CRC
+ elsif byteOffset = 3 then
+ writeContentData <= x"00000000";
+ crc16Current <= crc16Next; -- third frame's CRC
+ elsif byteOffset = 4 then
+ writeContentData <= crc16Next & X"0000"; -- write the CRC field
+ else
+ writeContent_o <= '0';
+ writeFrame_o <= '1';
+ readFrame_o <= '1';
+ stateRB <= WAIT_IDLE;
+ end if;
+
+ when SEND_FRAME =>
+ if (ftype = FTYPE_WRITE_CLASS) and (ttype = TTYPE_NWRITE_TRANSACTION) and (tt = "01") then -- check what type of pakage we got
+ readFrame_o <= '1';
+ elsif (ftype = FTYPE_REQUEST_CLASS) and (ttype = TTYPE_NREAD_TRANSACTION) and (tt = "01") then -- write payload to the buffer is done
+ readFrame_o <= '1';
+ writeFrame_o <= '1';
+ else -- the operation was not valid
+ readFrame_o <= '1';
+ writeFrame_o <= '1';
+ end if;
+ stateRB <= WAIT_IDLE;
+
+ when WAIT_IDLE =>
+ readFrame_o <= '0';
+ writeFrame_o <= '0';
+ readContent_o <= '0'; -- this line is to make sure that the CRC is complete read
+ stateRB <= IDLE;
+
+ when others =>
+ stateRB <= IDLE;
+
+ end case;
+
+ end if;
+
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- Configuration memory.
+ -----------------------------------------------------------------------------
+ memoryConfig : process(clk, areset_n)
+ begin
+ if (areset_n = '0') then
+ configDataRead <= (others => '0');
+ baseDeviceId <= DEFAULT_BASE_DEVICE_ID;
+ componentTag <= (others => '0');
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ elsif (clk'event and clk = '1') then
+
+ if (configEnable = '1') then
+ case (configAddress) is
+ when x"000000" =>
+ -- Device Identity CAR. Read-only.
+ configDataRead(31 downto 16) <= DEVICE_IDENTITY;
+ configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY;
+ when x"000004" =>
+ -- Device Information CAR. Read-only.
+ configDataRead(31 downto 0) <= DEVICE_REV;
+ when x"000008" =>
+ -- Assembly Identity CAR. Read-only.
+ configDataRead(31 downto 16) <= ASSY_IDENTITY;
+ configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY;
+ when x"00000c" =>
+ -- Assembly Informaiton CAR. Read-only.
+ -- Extended features pointer to "0000".
+ configDataRead(31 downto 16) <= ASSY_REV;
+ configDataRead(15 downto 0) <= x"0000";
+ when x"000010" =>
+ -- Processing Element Features CAR. Read-only.
+ -- Bridge(31), Memory(30), Processor(29), Switch(28).
+ configDataRead(31) <= '1';
+ configDataRead(30 downto 4) <= (others => '0');
+ configDataRead(3) <= '1'; -- support 16 bits common transport large system
+ configDataRead(2 downto 0) <= "001"; -- support 34 bits address
+ when x"000018" =>
+ -- Source Operations CAR. Read-only.
+ configDataRead(31 downto 0) <= (others => '0');
+ when x"00001C" =>
+ -- Destination Operations CAR. Read-only.
+ configDataRead(31 downto 16) <= (others => '0');
+ configDataRead(15) <= '1';
+ configDataRead(14) <= '1';
+ configDataRead(13 downto 0) <= (others => '0');
+ when x"00004C" =>
+ -- Processing Element Logical Layer Control CSR.
+ configDataRead(31 downto 3) <= (others => '0');
+ configDataRead(2 downto 0) <= "001"; -- support 34 bits address
+ when x"000060" =>
+ -- Base Device ID CSR.
+ -- Only valid for end point devices.
+ if (configWrite = '1') then
+ baseDeviceId <= configDataWrite(15 downto 0);
+ else
+ configDataRead(15 downto 0) <= baseDeviceId;
+ end if;
+ when x"000068" =>
+ -- Host Base Device ID Lock CSR.
+ if (configWrite = '1') then
+ -- Check if this field has been written before.
+ if (hostBaseDeviceIdLocked = '0') then
+ -- The field has not been written.
+ -- Lock the field and set the host base device id.
+ hostBaseDeviceIdLocked <= '1';
+ hostBaseDeviceId <= configDataWrite(15 downto 0);
+ else
+ -- The field has been written.
+ -- Check if the written data is the same as the stored.
+ if (hostBaseDeviceId = configDataWrite(15 downto 0)) then
+ -- Same as stored, reset the value to its initial value.
+ hostBaseDeviceIdLocked <= '0';
+ hostBaseDeviceId <= (others => '1');
+ else
+ -- Not writing the same as the stored value.
+ -- Ignore the write.
+ end if;
+ end if;
+ else
+ configDataRead(31 downto 16) <= (others => '0');
+ configDataRead(15 downto 0) <= hostBaseDeviceId;
+ end if;
+ when x"00006C" =>
+ -- Component TAG CSR.
+ if (configWrite = '1') then
+ componentTag <= configDataWrite;
+ else
+ configDataRead <= componentTag;
+ end if;
+
+ when others =>
+ configDataRead <= (others => '0');
+ end case;
+ else
+ -- Config memory not enabled.
+ end if;
+ end if;
+ end process;
+
+ -----------------------------------------------------------------------------
+ -- findInPayload
+ -- find out number of the bytes and first byte's position in the payload.
+ -----------------------------------------------------------------------------
+ findInPayload: process(wdptr, size)
+ begin
+ case size is
+ when "0000" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "0001" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 5;
+ else
+ pos <= 1;
+ end if;
+ when "0010" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 6;
+ else
+ pos <= 2;
+ end if;
+ when "0011" =>
+ reserved <= '0';
+ numberOfByte <= 1;
+ if wdptr = '1' then
+ pos <= 7;
+ else
+ pos <= 3;
+ end if;
+ when "0100" =>
+ reserved <= '0';
+ numberOfByte <= 2;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "0101" =>
+ reserved <= '0';
+ numberOfByte <= 3;
+ if wdptr = '1' then
+ pos <= 5;
+ else
+ pos <= 0;
+ end if;
+ when "0110" =>
+ reserved <= '0';
+ numberOfByte <= 2;
+ if wdptr = '1' then
+ pos <= 6;
+ else
+ pos <= 2;
+ end if;
+ when "0111" =>
+ reserved <= '0';
+ numberOfByte <= 5;
+ if wdptr = '1' then
+ pos <= 3;
+ else
+ pos <= 0;
+ end if;
+ when "1000" =>
+ reserved <= '0';
+ numberOfByte <= 4;
+ if wdptr = '1' then
+ pos <= 4;
+ else
+ pos <= 0;
+ end if;
+ when "1001" =>
+ reserved <= '0';
+ numberOfByte <= 6;
+ if wdptr = '1' then
+ pos <= 2;
+ else
+ pos <= 0;
+ end if;
+ when "1010" =>
+ reserved <= '0';
+ numberOfByte <= 7;
+ if wdptr = '1' then
+ pos <= 1;
+ else
+ pos <= 0;
+ end if;
+ when "1011" =>
+ reserved <= '0';
+ if wdptr = '1' then
+ numberOfByte <= 16;
+ else
+ numberOfByte <= 8;
+ end if;
+ pos <= 0;
+ when "1100" =>
+ reserved <= '0';
+ if wdptr = '1' then
+ numberOfByte <= 64;
+ else
+ numberOfByte <= 32;
+ end if;
+ pos <= 0;
+ when "1101" =>
+ if wdptr = '1' then
+ reserved <= '0';
+ numberOfByte <= 128;
+ else
+ reserved <= '1';
+ numberOfByte <= 96;
+ end if;
+ pos <= 0;
+ when "1110" =>
+ if wdptr = '1' then
+ numberOfByte <= 192;
+ else
+ numberOfByte <= 160;
+ end if;
+ reserved <= '1';
+ pos <= 0;
+ when "1111" =>
+ if wdptr = '1' then
+ reserved <= '0';
+ numberOfByte <= 256;
+ else
+ reserved <= '1';
+ numberOfByte <= 224;
+ end if;
+ pos <= 0;
+ when others =>
+ reserved <= '1';
+ numberOfByte <= 0;
+ pos <= 0;
+ end case;
+ end process;
+
+end architecture;
tags/1.0.2-release/rtl/vhdl/RioWbBridge.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: tags/1.0.2-release/doc/rio.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: tags/1.0.2-release/doc/rio.pdf
===================================================================
--- tags/1.0.2-release/doc/rio.pdf (nonexistent)
+++ tags/1.0.2-release/doc/rio.pdf (revision 50)
tags/1.0.2-release/doc/rio.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: tags/1.0.2-release/doc/rio.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: tags/1.0.2-release/doc/rio.odt
===================================================================
--- tags/1.0.2-release/doc/rio.odt (nonexistent)
+++ tags/1.0.2-release/doc/rio.odt (revision 50)
tags/1.0.2-release/doc/rio.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property