OpenCores
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 47 to Rev 48
    Reverse comparison

Rev 47 → Rev 48

/branches/2.0.0-development/bench/vhdl/TestRioWbBridge.vhd
9,7 → 9,6
-- Contains automatic test code to verify a RioWbBridge implementation.
--
-- To Do:
-- - Move the testport package and entities to a seperate file.
-- - Add testcases to NWRITE to cover all possible access lengths, not just the
-- maximum as presently.
--
439,7 → 438,18
wdptr := '1';
end if;
CreateRandomPayload(ioData, seed1, seed2);
ioData(0) := x"0001020304050607";
ioData(1) := x"08090a0b0c0d0e0f";
ioData(2) := x"1011121314151617";
ioData(3) := x"18191a1b1c1d1e1f";
ioData(4) := x"2021222324252627";
ioData(5) := x"28292a2b2c2d2e2f";
ioData(6) := x"3031323334353637";
ioData(7) := x"38393a3b3c3d3e3f";
ioData(8) := x"4041424344454647";
ioData(9) := x"48494a4b4c4d4e4f";
ioData(10) := x"5051525354555657";
ioData(11) := x"58595a5b5c5d5e5f";
 
InboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_REQUEST_CLASS,
/branches/2.0.0-development/bench/vhdl/TestPortPackage.vhd
49,6 → 49,7
library ieee;
use ieee.std_logic_1164.all;
use work.rio_common.all;
use std.textio.all;
 
-------------------------------------------------------------------------------
--
169,6 → 170,53
constant frame : in RioFrame;
constant willAbort : in boolean := false);
 
-----------------------------------------------------------------------------
-- Function to print a std_logic_vector.
-----------------------------------------------------------------------------
function to_string(constant value : std_logic_vector)
return string;
---------------------------------------------------------------------------
-- Procedures for test control.
---------------------------------------------------------------------------
 
procedure TestWarning(constant tag : in string);
procedure TestError(constant tag : in string;
constant stopAtError : in boolean := true);
procedure TestCompare(constant expression : in boolean;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in std_logic;
constant expected : in std_logic;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in std_logic_vector;
constant expected : in std_logic_vector;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in natural;
constant expected : in natural;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in time;
constant expected : in time;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true);
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
signal ackSignal : inout std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true);
 
procedure TestEnd;
 
end package;
 
-------------------------------------------------------------------------------
220,6 → 268,259
wait until ackSignal = '0';
end procedure;
-----------------------------------------------------------------------------
-- Function to print std_logic_vector.
-----------------------------------------------------------------------------
function to_string(constant value : std_logic) return string is
variable s : string(1 to 1);
begin
if (value = '0') then
s(1) := '0';
elsif (value = '1') then
s(1) := '1';
elsif (value = 'U') then
s(1) := 'U';
elsif (value = 'X') then
s(1) := 'X';
else
s(1) := '?';
end if;
return s;
end function;
function to_string(constant value : std_logic_vector) return string is
variable s : string(1 to value'length);
variable index : positive;
variable i : natural;
begin
index := 1;
for i in value'range loop
if (value(i) = '0') then
s(index) := '0';
elsif (value(i) = '1') then
s(index) := '1';
elsif (value(i) = 'U') then
s(index) := 'U';
elsif (value(i) = 'X') then
s(index) := 'X';
else
s(index) := '?';
end if;
index := index + 1;
end loop;
return s;
end function;
---------------------------------------------------------------------------
-- Procedures to handle tests.
---------------------------------------------------------------------------
 
procedure TestWarning(constant tag : in string) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":WARNING:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
end procedure;
procedure TestError(constant tag : in string;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant expression : in boolean;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (not expression) then
write(writeBuffer, string'(":FAILED:"));
else
write(writeBuffer, string'(":PASSED:"));
end if;
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) and (not expression) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in std_logic;
constant expected : in std_logic;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & to_string(got));
write(writeBuffer, ":expected=" & to_string(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in std_logic_vector;
constant expected : in std_logic_vector;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & to_string(got));
write(writeBuffer, ":expected=" & to_string(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in natural;
constant expected : in natural;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & integer'image(got));
write(writeBuffer, ":expected=" & integer'image(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in time;
constant expected : in time;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, string'(":got="));
write(writeBuffer, got);
write(writeBuffer, string'(":expected="));
write(writeBuffer, expected);
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
 
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
if (waitSignal /= waitValue) then
wait until waitSignal = waitValue for waitTime;
if (waitSignal /= waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end if;
end procedure;
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
signal ackSignal : inout std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
if (waitSignal /= waitValue) then
 
wait until waitSignal = waitValue for waitTime;
if (waitSignal /= waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end if;
ackSignal <= not ackSignal;
wait until waitSignal /= waitValue for waitTime;
if (waitSignal = waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end procedure;
 
procedure TestEnd is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":COMPLETED"));
writeline(OUTPUT, writeBuffer);
std.env.stop(0);
end TestEnd;
 
end package body;
 
 
282,7 → 583,7
--
-------------------------------------------------------------------------------
architecture TestPortPacketBufferPortImpl of TestPortPacketBuffer is
constant QUEUE_SIZE : natural := 63;
constant QUEUE_SIZE : natural := 255;
type QueueArray is array (natural range <>) of TestPortMessagePacketBuffer;
function QueueIndexInc(constant i : natural) return natural is
327,6 → 628,9
 
if (clk'event) then
if (readFrame_i = '1') then
if ((not frameQueue(back).willAbort) and (frameIndex < frameQueue(back).frame.length)) then
TestError("READ:BACK:reading unfinished frame");
end if;
if (back /= front) then
back := QueueIndexInc(back);
else
409,6 → 713,9
elsif (readWrite_i'event) then
frameQueue(front) := readMessage_i;
front := QueueIndexInc(front);
if (front = back) then
TestError("Queue full");
end if;
 
readEmpty_o <= '0';
readAck_o <= '1';
488,6 → 795,9
elsif (writeWrite_i'event) then
frameQueue(front) := writeMessage_i;
front := QueueIndexInc(front);
if (front = back) then
TestError("Queue full");
end if;
 
writeEmpty_o <= '0';
writeAck_o <= '1';
/branches/2.0.0-development/bench/vhdl/TestRioSerial.vhd
9,7 → 9,8
-- Contains automatic simulation test code to verify a RioSerial implementation.
--
-- To Do:
-- -
-- - Replace TestSwitchPort with generic TestPortPacketBuffer from common library.
-- - Move TestSymbolPort to generic library.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
80,6 → 81,7
use std.textio.all;
use work.rio_common.all;
use work.TestRioSerialPackage.all;
use work.TestPortPackage.all;
 
 
-------------------------------------------------------------------------------
2562,6 → 2564,7
use std.textio.all;
use work.rio_common.all;
use work.TestRioSerialPackage.all;
use work.TestPortPackage.all;
 
 
-------------------------------------------------------------------------------
2821,6 → 2824,7
use std.textio.all;
use work.rio_common.all;
use work.TestRioSerialPackage.all;
use work.TestPortPackage.all;
 
 
-------------------------------------------------------------------------------
/branches/2.0.0-development/bench/vhdl/TestRioSwitch.vhd
9,7 → 9,6
-- Contains automatic simulation test code to verify a RioSwitch implementation.
--
-- To Do:
-- - Use the Wishbone port as a test port on the implementation defined config-space.
-- - Test all sizes of packets that go through the maintenance port.
--
-- Author(s):
567,43 → 566,43
 
-- 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");
tid=>x"01", 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");
tid=>x"02", 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");
tid=>x"03", 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");
tid=>x"04", 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");
tid=>x"05", 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");
tid=>x"06", 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");
tid=>x"07", 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");
tid=>x"08", 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");
tid=>x"09", 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");
tid=>x"0a", address=>x"000068", data=>x"0000ffff");
ExchangeFrames;
 
874,7 → 873,7
data=>maintData)));
 
ExchangeFrames;
TestWait(messageEmpty, '1', "config read");
TestWait(messageEmpty, '1', "config write");
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
/branches/2.0.0-development/bench/vhdl/TestRioLogicalCommon.vhd
45,7 → 45,6
-------------------------------------------------------------------------------
-- TestRioLogicalCommon.
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
53,6 → 52,7
library std;
use std.textio.all;
use work.rio_common.all;
use work.TestPortPackage.all;
 
 
-------------------------------------------------------------------------------
67,71 → 67,20
-------------------------------------------------------------------------------
architecture TestRioLogicalCommonImpl of TestRioLogicalCommon is
component RioLogicalCommon is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : 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);
 
configStb_o : out std_logic;
configWe_o : out std_logic;
configAdr_o : out std_logic_vector(21 downto 0);
configDat_o : out std_logic_vector(31 downto 0);
configDat_i : in std_logic_vector(31 downto 0);
configAck_i : in std_logic);
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;
readFrameRestart_i : in std_logic;
readFrameAborted_o : out 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;
 
signal outboundMessageEmpty : std_logic;
signal outboundMessageWrite : std_logic;
signal outboundMessageMessage : TestPortMessagePacketBuffer;
signal outboundMessageAck : std_logic;
signal inboundMessageEmpty : std_logic;
signal inboundMessageWrite : std_logic;
signal inboundMessageMessage : TestPortMessagePacketBuffer;
signal inboundMessageAck : std_logic;
signal clk : std_logic;
signal areset_n : std_logic;
signal enable : std_logic;
 
signal frameValid : std_logic;
signal frameWrite : RioFrame;
signal frameComplete : std_logic;
signal frameExpected : std_logic;
signal frameRead : RioFrame;
signal frameReceived : std_logic;
signal writeFrameFull : std_logic;
signal writeFrame : std_logic;
signal writeFrameAbort : std_logic;
147,12 → 96,15
signal readContentEnd : std_logic;
signal readContentData : std_logic_vector(31 downto 0);
 
signal configStb, configStbExpected : std_logic;
signal configWe : std_logic;
signal configAddr : std_logic_vector(21 downto 0);
signal configDataWrite : std_logic_vector(31 downto 0);
signal configDataRead : std_logic_vector(31 downto 0);
signal configAck : std_logic;
signal inboundStb : std_logic;
signal inboundAdr : std_logic_vector(3 downto 0);
signal inboundDat : std_logic_vector(31 downto 0);
signal inboundStall : std_logic;
 
signal outboundStb : std_logic_vector(0 downto 0);
signal outboundAdr : std_logic_vector(0 downto 0);
signal outboundDat : std_logic_vector(31 downto 0);
signal outboundStall : std_logic_vector(0 downto 0);
begin
173,44 → 125,148
-----------------------------------------------------------------------------
TestDriver: process
 
-----------------------------------------------------------------------------
-- Procedures to handle outbound and inbound packets.
-----------------------------------------------------------------------------
procedure OutboundFrame(constant frame : in RioFrame;
constant abort : in boolean := false) is
begin
TestPortPacketBufferWrite(outboundMessageWrite, outboundMessageMessage, outboundMessageAck,
frame, abort);
end procedure;
procedure InboundFrame(constant frame : in RioFrame;
constant abort : in boolean := false) is
begin
TestPortPacketBufferWrite(inboundMessageWrite, inboundMessageMessage, inboundMessageAck,
frame, abort);
end procedure;
 
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
procedure SendFrame(constant frame : RioFrame) is
procedure InboundPayload(constant header : in std_logic_vector(15 downto 0);
constant dstId : in std_logic_vector(15 downto 0);
constant srcId : in std_logic_vector(15 downto 0);
constant payload : in RioPayload) is
variable adr : std_logic_vector(3 downto 0);
begin
frameValid <= '1';
frameWrite <= frame;
wait until frameComplete = '1';
frameValid <= '0';
wait until clk = '1';
while (inboundStb = '0') loop
wait until clk = '1';
end loop;
adr := inboundAdr;
TestCompare(inboundStb, '1', "stb header");
TestCompare(inboundAdr, header(3 downto 0), "adr");
TestCompare(inboundDat, x"0000" & header, "header");
wait until clk = '1';
TestCompare(inboundStb, '1', "stb dstId");
TestCompare(inboundAdr, adr, "adr dstId");
TestCompare(inboundDat, x"0000" & dstId, "dstId");
wait until clk = '1';
TestCompare(inboundStb, '1', "stb srcId");
TestCompare(inboundAdr, adr, "adr srcId");
TestCompare(inboundDat, x"0000" & srcId, "srcId");
 
for i in 0 to (payload.length/2)-1 loop
wait until clk = '1';
TestCompare(inboundStb, '1', "stb payload");
TestCompare(inboundAdr, adr, "adr payload");
TestCompare(inboundDat, payload.data(2*i) & payload.data(2*i+1), "payload");
end loop;
 
if ((payload.length mod 2) = 1) then
-- Check the last half-word of payload that has CRC appended to it.
wait until clk = '1';
TestCompare(inboundStb, '1', "stb payload");
TestCompare(inboundAdr, adr, "adr payload");
TestCompare(inboundDat(31 downto 16), payload.data(payload.length-1), "payload");
else
if (payload.length >= 38) then
-- Ignore the last word since it contains only CRC and padding.
wait until clk = '1';
TestCompare(inboundStb, '1', "stb crc+pad");
TestCompare(inboundAdr, adr, "adr crc+pad");
TestCompare(inboundDat(15 downto 0), x"0000", "crc+pad");
end if;
end if;
wait until clk = '1';
TestCompare(inboundStb, '0', "stb end");
end procedure;
 
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
procedure ReceiveFrame(constant frame : RioFrame) is
procedure OutboundPayload(constant header : in std_logic_vector(15 downto 0);
constant dstId : in std_logic_vector(15 downto 0);
constant srcId : in std_logic_vector(15 downto 0);
constant payload : in RioPayload) is
begin
frameExpected <= '1';
frameRead <= frame;
wait until frameReceived = '1';
frameExpected <= '0';
if ((payload.length mod 2) = 1) then
outboundAdr(0) <= '1';
else
outboundAdr(0) <= '0';
end if;
outboundStb(0) <= '1';
outboundDat <= "UUUUUUUUUUUUUUUU" & header;
wait until clk = '1';
while (outboundStall(0) = '1') loop
wait until clk = '1';
end loop;
 
outboundDat <= "UUUUUUUUUUUUUUUU" & dstId;
wait until clk = '1';
while (outboundStall(0) = '1') loop
wait until clk = '1';
end loop;
outboundDat <= "UUUUUUUUUUUUUUUU" & srcId;
wait until clk = '1';
while (outboundStall(0) = '1') loop
wait until clk = '1';
end loop;
 
for i in 0 to (payload.length/2)-1 loop
outboundDat <= payload.data(2*i) & payload.data(2*i+1);
wait until clk = '1';
while (outboundStall(0) = '1') loop
wait until clk = '1';
end loop;
end loop;
 
if ((payload.length mod 2) = 1) then
outboundDat <= payload.data(payload.length-1) & "UUUUUUUUUUUUUUUU";
wait until clk = '1';
while (outboundStall(0) = '1') loop
wait until clk = '1';
end loop;
end if;
outboundStb(0) <= '0';
outboundAdr(0) <= 'U';
outboundDat <= (others=>'U');
wait until clk = '1';
end procedure;
 
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
variable seed1 : positive := 1;
variable seed2: positive := 1;
 
variable maintData : DoubleWordArray(0 to 7);
variable frame : RioFrame;
variable payload : RioPayload;
begin
areset_n <= '0';
enable <= '1';
 
frameValid <= '0';
frameExpected <= '0';
 
configStbExpected <= '0';
configAck <= '0';
writeFrameFull <= '0';
inboundStall <= '0';
outboundStb(0) <= '0';
wait until clk'event and clk = '1';
wait until clk'event and clk = '1';
areset_n <= '1';
222,1025 → 278,92
PrintS("TG_RioLogicalCommon");
PrintS("-----------------------------------------------------------------");
PrintS("TG_RioLogicalCommon-TC1");
PrintS("Description: Test maintenance read requests.");
PrintS("Requirement: XXXXX");
PrintS("Description: Test all sizes of packets in the inbound direction.");
PrintS("Requirement: ");
PrintS("-----------------------------------------------------------------");
PrintS("Step 1:");
PrintS("Action: Send maintenance read request for one word on even offset.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("Action: Add inbound packets in all allowed sized.");
PrintS("Result: The payload of the inbound packets should be received on ");
PrintS(" the other side without CRC.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step1");
---------------------------------------------------------------------------
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
-- REMARK: Use random data...
for j in 1 to 133 loop
payload.length := j;
for i in 0 to payload.length-1 loop
payload.data(i) := std_logic_vector(to_unsigned(i, 16));
end loop;
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_WRITE_CLASS,
destId=>x"beef", sourceId=>x"dead",
payload=>payload);
InboundFrame(frame);
end loop;
 
wait until configStb = '1';
configStbExpected <= '1';
wait until clk = '1';
assert configWe = '0';
assert configAddr = "0000000000000000000000";
wait until clk = '1';
configDataRead <= x"deadbeef";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
configStbExpected <= '0';
maintData(0) := x"deadbeef00000000";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>1,
data=>maintData)));
for j in 1 to 133 loop
payload.length := j;
InboundPayload(x"0015", x"beef", x"dead", payload);
end loop;
 
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 2:");
PrintS("Action: Send maintenance read request for one word on odd offset.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step2");
---------------------------------------------------------------------------
TestWait(inboundMessageEmpty, '1', "inboundMessage empty");
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'1',
dataLength=>0,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000001" report "Unexpected config address." severity error;
configDataRead <= x"c0debabe";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
configStbExpected <= '0';
maintData(0) := x"00000000c0debabe";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>1,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 3:");
PrintS("Action: Send maintenance read request for two words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
--PrintS("-----------------------------------------------------------------");
--PrintS("Step 2:");
--PrintS("Action: Send an inbound frame that are too long.");
--PrintS("Result: The tail of the packet should be discarded.");
--PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step3");
--PrintR("TG_RioLogicalCommon-TC1-Step2");
---------------------------------------------------------------------------
 
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1011",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
configDataRead <= x"11111111";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
configDataRead <= x"22222222";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
maintData(0) := x"1111111122222222";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>1,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 4:");
PrintS("Action: Send maintenance read request for four words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step4");
---------------------------------------------------------------------------
 
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1011",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'1',
dataLength=>0,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
configDataRead <= x"11111111";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
configDataRead <= x"22222222";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
configDataRead <= x"33333333";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
configDataRead <= x"44444444";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>2,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 5:");
PrintS("Action: Send maintenance read request for eight words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step5");
---------------------------------------------------------------------------
 
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1100",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
configDataRead <= x"11111111";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
configDataRead <= x"22222222";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
configDataRead <= x"33333333";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
configDataRead <= x"44444444";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error;
configDataRead <= x"55555555";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error;
configDataRead <= x"66666666";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error;
configDataRead <= x"77777777";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error;
configDataRead <= x"88888888";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
maintData(2) := x"5555555566666666";
maintData(3) := x"7777777788888888";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>4,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 6:");
PrintS("Action: Send maintenance read request for sixteen words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC1-Step6");
---------------------------------------------------------------------------
 
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0000",
size=>"1100",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'1',
dataLength=>0,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
configDataRead <= x"11111111";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
configDataRead <= x"22222222";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
configDataRead <= x"33333333";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
configDataRead <= x"44444444";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error;
configDataRead <= x"55555555";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error;
configDataRead <= x"66666666";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error;
configDataRead <= x"77777777";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error;
configDataRead <= x"88888888";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001010" report "Unexpected config address." severity error;
configDataRead <= x"99999999";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001011" report "Unexpected config address." severity error;
configDataRead <= x"aaaaaaaa";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001100" report "Unexpected config address." severity error;
configDataRead <= x"bbbbbbbb";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001101" report "Unexpected config address." severity error;
configDataRead <= x"cccccccc";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001110" report "Unexpected config address." severity error;
configDataRead <= x"dddddddd";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001111" report "Unexpected config address." severity error;
configDataRead <= x"eeeeeeee";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000010000" report "Unexpected config address." severity error;
configDataRead <= x"ffffffff";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '0' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000010001" report "Unexpected config address." severity error;
configDataRead <= x"10101010";
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
maintData(2) := x"5555555566666666";
maintData(3) := x"7777777788888888";
maintData(4) := x"99999999aaaaaaaa";
maintData(5) := x"bbbbbbbbcccccccc";
maintData(6) := x"ddddddddeeeeeeee";
maintData(7) := x"ffffffff10101010";
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0010",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>8,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("TG_RioLogicalCommon-TC2");
PrintS("Description: Test maintenance write requests.");
PrintS("Requirement: XXXXX");
PrintS("Description: Test all sizes of packets in the outbound direction.");
PrintS("Requirement: ");
PrintS("-----------------------------------------------------------------");
PrintS("Step 1:");
PrintS("Action: Send maintenance write request for one word on even offset.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("Action: Add outbound packets in all allowed sized.");
PrintS("Result: The payload of the outbound packets should be received on ");
PrintS(" the other side with CRC added.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step1");
---------------------------------------------------------------------------
 
maintData(0) := x"deadbeef00000000";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"100000000000000000000",
wdptr=>'0',
dataLength=>1,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
for j in 1 to 133 loop
payload.length := j;
for i in 0 to payload.length-1 loop
payload.data(i) := std_logic_vector(to_unsigned(i, 16));
end loop;
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_WRITE_CLASS,
destId=>x"beef", sourceId=>x"dead",
payload=>payload);
OutboundFrame(frame);
end loop;
wait until clk = '1';
assert configWe = '1' report "Unexpected configWe." severity error;
assert configAddr = "1000000000000000000000" report "Unexpected configAddr." severity error;
assert configDataWrite = x"deadbeef" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
for j in 1 to 133 loop
payload.length := j;
OutboundPayload(x"0015", x"beef", x"dead", payload);
end loop;
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 2:");
PrintS("Action: Send maintenance write request for one word on odd offset.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step2");
---------------------------------------------------------------------------
TestWait(outboundMessageEmpty, '1', "outboundMessage empty");
maintData(0) := x"00000000c0debabe";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"100000000000000000000",
wdptr=>'1',
dataLength=>1,
data=>maintData)));
-----------------------------------------------------------------------------
--PrintS("-----------------------------------------------------------------");
--PrintS("Step 2:");
--PrintS("Action: Send an outbound frame that are too long.");
--PrintS("Result: The tail of the packet should be discarded.");
--PrintS("-----------------------------------------------------------------");
-----------------------------------------------------------------------------
--PrintR("TG_RioLogicalCommon-TC1-Step2");
-----------------------------------------------------------------------------
 
wait until configStb = '1';
configStbExpected <= '1';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "1000000000000000000001" report "Unexpected config address." severity error;
assert configDataWrite = x"c0debabe" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"aa",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 3:");
PrintS("Action: Send maintenance write request for two words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step3");
---------------------------------------------------------------------------
 
maintData(0) := x"1111111122222222";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1011",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"100000000000000000001",
wdptr=>'0',
dataLength=>1,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "1000000000000000000010" report "Unexpected config address." severity error;
assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "1000000000000000000011" report "Unexpected config address." severity error;
assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 4:");
PrintS("Action: Send maintenance write request for four words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step4");
---------------------------------------------------------------------------
 
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1011",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'1',
dataLength=>2,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 5:");
PrintS("Action: Send maintenance write request for eight words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step5");
---------------------------------------------------------------------------
 
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
maintData(2) := x"5555555566666666";
maintData(3) := x"7777777788888888";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1100",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'0',
dataLength=>4,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error;
assert configDataWrite = x"55555555" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error;
assert configDataWrite = x"66666666" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error;
assert configDataWrite = x"77777777" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error;
assert configDataWrite = x"88888888" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
---------------------------------------------------------------------------
PrintS("-----------------------------------------------------------------");
PrintS("Step 6:");
PrintS("Action: Send maintenance write request for sixteen words.");
PrintS("Result: Check the accesses on the external configuration port.");
PrintS("-----------------------------------------------------------------");
---------------------------------------------------------------------------
PrintR("TG_RioLogicalCommon-TC2-Step6");
---------------------------------------------------------------------------
 
maintData(0) := x"1111111122222222";
maintData(1) := x"3333333344444444";
maintData(2) := x"5555555566666666";
maintData(3) := x"7777777788888888";
maintData(4) := x"99999999aaaaaaaa";
maintData(5) := x"bbbbbbbbcccccccc";
maintData(6) := x"ddddddddeeeeeeee";
maintData(7) := x"ffffffff10101010";
SendFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"dead", destId=>x"beef",
payload=>RioMaintenance(transaction=>"0001",
size=>"1100",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000001",
wdptr=>'1',
dataLength=>8,
data=>maintData)));
 
wait until configStb = '1';
configStbExpected <= '1';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000010" report "Unexpected config address." severity error;
assert configDataWrite = x"11111111" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000011" report "Unexpected config address." severity error;
assert configDataWrite = x"22222222" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000100" report "Unexpected config address." severity error;
assert configDataWrite = x"33333333" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000101" report "Unexpected config address." severity error;
assert configDataWrite = x"44444444" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000110" report "Unexpected config address." severity error;
assert configDataWrite = x"55555555" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000000111" report "Unexpected config address." severity error;
assert configDataWrite = x"66666666" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001000" report "Unexpected config address." severity error;
assert configDataWrite = x"77777777" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001001" report "Unexpected config address." severity error;
assert configDataWrite = x"88888888" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001010" report "Unexpected config address." severity error;
assert configDataWrite = x"99999999" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001011" report "Unexpected config address." severity error;
assert configDataWrite = x"aaaaaaaa" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001100" report "Unexpected config address." severity error;
assert configDataWrite = x"bbbbbbbb" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001101" report "Unexpected config address." severity error;
assert configDataWrite = x"cccccccc" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001110" report "Unexpected config address." severity error;
assert configDataWrite = x"dddddddd" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000001111" report "Unexpected config address." severity error;
assert configDataWrite = x"eeeeeeee" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000010000" report "Unexpected config address." severity error;
assert configDataWrite = x"ffffffff" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
wait until clk = '1';
assert configWe = '1' report "Unexpected config write." severity error;
assert configAddr = "0000000000000000010001" report "Unexpected config address." severity error;
assert configDataWrite = x"10101010" report "Unexpected configDataWrite." severity error;
configAck <= '1';
wait until clk = '1';
configAck <= '0';
 
configStbExpected <= '0';
ReceiveFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00",
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS,
sourceId=>x"beef", destId=>x"dead",
payload=>RioMaintenance(transaction=>"0011",
size=>"0000",
tid=>x"cc",
hopCount=>x"ff",
configOffset=>"000000000000000000000",
wdptr=>'0',
dataLength=>0,
data=>maintData)));
 
 
---------------------------------------------------------------------------
-- Test completed.
---------------------------------------------------------------------------
1248,273 → 371,64
end process;
 
-----------------------------------------------------------------------------
-- Instantiate a process receiving the configuration accesses to the
-- implementation defined space.
-- Instantiate the test port.
-----------------------------------------------------------------------------
process
begin
loop
wait until clk'event and clk = '1';
assert configStbExpected = configStb report "Unexpected config-space access." severity error;
end loop;
end process;
-----------------------------------------------------------------------------
-- Instantiate the test port array.
-----------------------------------------------------------------------------
 
readFrameRestart <= '0';
TestPortInst: TestPort
TestPortPacketBufferInst: TestPortPacketBuffer
generic map(READ_CONTENT_END_DATA_VALID=>false)
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,
readEmpty_o=>inboundMessageEmpty,
readWrite_i=>inboundMessageWrite,
readMessage_i=>inboundMessageMessage,
readAck_o=>inboundMessageAck,
writeEmpty_o=>outboundMessageEmpty,
writeWrite_i=>outboundMessageWrite,
writeMessage_i=>outboundMessageMessage,
writeAck_o=>outboundMessageAck,
readFrameEmpty_o=>readFrameEmpty,
readFrame_i=>readFrame,
readFrameRestart_i=>readFrameRestart,
readFrameAborted_o=>readFrameAborted,
readFrameRestart_i=>'0',
readFrameAborted_o=>readFrameAborted,
readWindowEmpty_o=>open,
readWindowReset_i=>'0',
readWindowNext_i=>readFrame,
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);
 
-----------------------------------------------------------------------------
-- Instantiate the switch.
-- Instantiate the test object.
-----------------------------------------------------------------------------
 
TestObject: RioLogicalCommon
generic map(PORTS=>1)
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
clk=>clk,
areset_n=>areset_n,
enable=>enable,
readFrameEmpty_i=>readFrameEmpty,
readFrame_o=>readFrame,
readContent_o=>readContent,
readContentEnd_i=>readContentEnd,
readContentData_i=>readContentData,
writeFrameFull_i=>writeFrameFull,
writeFrame_o=>writeFrame,
writeFrameAbort_o=>writeFrameAbort,
writeFrameAbort_o=>writeFrameAbort,
writeContent_o=>writeContent,
writeContentData_o=>writeContentData,
readFrameEmpty_i=>readFrameEmpty,
readFrame_o=>readFrame,
readContent_o=>readContent,
readContentEnd_i=>readContentEnd,
readContentData_i=>readContentData,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAddr,
configDat_o=>configDataWrite,
configDat_i=>configDataRead,
configAck_i=>configAck);
writeContentData_o=>writeContentData,
inboundStb_o=>inboundStb,
inboundAdr_o=>inboundAdr,
inboundDat_o=>inboundDat,
inboundStall_i=>inboundStall,
outboundStb_i=>outboundStb,
outboundAdr_i=>outboundAdr,
outboundDat_i=>outboundDat,
outboundStall_o=>outboundStall);
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 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;
readFrameRestart_i : in std_logic;
readFrameAborted_o : out 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 TestPortImpl of TestPort is
begin
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
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;
 
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
-- REMARK: add support for these signals...
-- readFrameEmpty_i : in std_logic;
-- readFrameAborted_i : in std_logic;
FrameSender: process
type StateType is (STATE_IDLE, STATE_READ);
variable state : StateType;
variable frameIndex : natural range 0 to 69;
begin
readFrameEmpty_o <= '1';
readFrameAborted_o <= '0';
readContentEmpty_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;
readContentEmpty_o <= '0';
readFrameEmpty_o <= '0';
else
readContentEmpty_o <= '1';
end if;
when STATE_READ =>
if (readFrameRestart_i = '1') then
readContentEnd_o <= '0';
frameIndex := 0;
else
-- Not restarting a frame.
end if;
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';
readContentEmpty_o <= '1';
readContentData_o <= (others => 'U');
else
-- Not reading a frame.
end if;
 
end case;
end loop;
end process;
 
end architecture;
/branches/2.0.0-development/rtl/vhdl/RioLogicalPackets.vhd
9,12 → 9,7
-- Containing RapidIO packet parsers and generators.
--
-- To Do:
-- - Add support for maint-request and response in both directions.
-- - Add support for portWrite in both directions.
-- - Add generic to disable support for specified packets.
-- - Dont set complete before the packet is ready in inbound packet
-- handler.
-- - Add error indication if erronous sizes are received.
-- -
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
60,6 → 55,12
-- Entity for MaintenanceInbound.
-------------------------------------------------------------------------------
entity MaintenanceInbound is
generic(
ENABLE_READ_REQUEST : boolean := true;
ENABLE_WRITE_REQUEST : boolean := true;
ENABLE_READ_RESPONSE : boolean := true;
ENABLE_WRITE_RESPONSE : boolean := true;
ENABLE_PORT_WRITE : boolean := true);
port(
clk : in std_logic;
areset_n : in std_logic;
87,11 → 88,10
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
inboundStall_o : out std_logic);
end entity;
 
 
100,21 → 100,18
-------------------------------------------------------------------------------
architecture MaintenanceInbound of MaintenanceInbound is
 
type StateType is (RECEIVE_PACKET, READY);
signal state : StateType;
signal busy : std_ulogic;
signal transaction : std_logic_vector(3 downto 0);
signal payloadIndex : unsigned(2 downto 0);
signal packetIndex : natural range 0 to 21;
signal packetData : std_logic_vector(47 downto 0);
 
signal wdptr : std_logic;
signal size : std_logic_vector(3 downto 0);
 
signal inboundAck : std_logic;
signal readRequestComplete : std_logic;
signal writeRequestComplete : std_logic;
signal readResponseComplete : std_logic;
signal writeResponseComplete : std_logic;
signal portWriteComplete : std_logic;
 
signal packetIndex : natural range 0 to 21;
signal packetData : std_logic_vector(47 downto 0);
 
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(2 downto 0);
signal memoryDataIn : std_logic_vector(63 downto 0);
121,22 → 118,24
 
begin
 
readRequestReady_o <= readRequestComplete when (state = READY) else '0';
writeRequestReady_o <= writeRequestComplete when (state = READY) else '0';
readResponseReady_o <= readResponseComplete when (state = READY) else '0';
writeResponseReady_o <= writeResponseComplete when (state = READY) else '0';
portWriteReady_o <= '0';
readRequestReady_o <= readRequestComplete and busy;
writeRequestReady_o <= writeRequestComplete and busy;
readResponseReady_o <= readResponseComplete and busy;
writeResponseReady_o <= writeResponseComplete and busy;
portWriteReady_o <= portWriteComplete and busy;
 
inboundAck_o <= inboundAck;
payloadLength_o <= std_logic_vector(payloadIndex);
 
inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"8")) else '0';
MaintenanceRequest: process(clk, areset_n)
begin
if (areset_n = '0') then
inboundAck <= '0';
 
readRequestComplete <= '0';
writeRequestComplete <= '0';
readResponseComplete <= '0';
writeResponseComplete <= '0';
portWriteComplete <= '0';
vc_o <= '0';
crf_o <= '0';
149,8 → 148,12
hop_o <= (others=>'0');
offset_o <= (others=>'0');
 
wdptr <= '0';
size <= (others=>'0');
wdptr_o <= '0';
size_o <= (others=>'0');
 
busy <= '0';
transaction <= "0000";
payloadIndex <= "000";
packetIndex <= 0;
memoryWrite <= '0';
157,264 → 160,741
memoryAddress <= (others=>'0');
memoryDataIn <= (others=>'0');
elsif (clk'event and clk = '1') then
case state is
when RECEIVE_PACKET =>
if (enable = '1') then
if (busy = '0') then
---------------------------------------------------------------------
-- This state waits for a new maintenance packet, receives it
-- and parses it.
---------------------------------------------------------------------
if (inboundCyc_i = '1') then
if (inboundAck = '0') then
if (inboundStb_i = '1') then
if (inboundAdr_i = x"80") then
-------------------------------------------------------------
-- Maintenance Read Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
size <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
packetIndex <= packetIndex + 1;
readRequestComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
--report "Received unexpected packet content in read request." severity warning;
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"81") then
-------------------------------------------------------------
-- Maintenance Write Request packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & hop & config_offset(20:13)
size <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48)
offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
-- double-word(47:16)
packetData(31 downto 0) <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 =>
-- double-word(15:0) & double-word(63:48)
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
memoryWrite <= '1';
memoryDataIn <= packetData & inboundDat_i(31 downto 16);
writeRequestComplete <= '1';
when others =>
-- There should be no more content in a maintenance write request.
-- Discard.
--report "Received unexpected packet content in write request." severity warning;
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"82") then
-------------------------------------------------------------
-- Maintenance Read Response packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destid
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & srcTID & hop & reserved(7:0)
status_o <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
packetIndex <= packetIndex + 1;
when 4 =>
-- reserved(15:0) & wdptr & rsrv & double-word(63:48)
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
-- double-word(47:16)
packetData(31 downto 0) <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 =>
-- double-word(15:0) & double-word(63:48)
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
memoryWrite <= '1';
memoryDataIn <= packetData & inboundDat_i(31 downto 16);
readResponseComplete <= '1';
when others =>
-- There should be no more content in a maintenance write request.
-- Discard.
--report "Received unexpected packet content in read response." severity warning;
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"83") then
-------------------------------------------------------------
-- Maintenance Write Response packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & srcTID & hop & reserved(7:0)
status_o <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
packetIndex <= packetIndex + 1;
when 4 =>
-- reserved(15:0) & crc(15:0)
packetIndex <= packetIndex + 1;
writeResponseComplete <= '1';
when others =>
-- There should be no more content in a maintenance read request.
-- Discard.
--report "Received unexpected packet content in write response." severity warning;
end case;
inboundAck <= '1';
elsif (inboundAdr_i = x"84") then
-------------------------------------------------------------
-- Maintenance Port-Write Request packet parser.
-------------------------------------------------------------
else
-------------------------------------------------------------
-- Unsupported maintenance packet.
-------------------------------------------------------------
-- Cannot handle these, dont answer.
if (inboundStb_i = '1') and (inboundAdr_i = x"8") then
-- New inbound packet content.
case (packetIndex) is
 
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
 
when 1 =>
-- dstid
dstid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
 
when 2 =>
-- srcid
srcid_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
 
when 3 =>
-- READ-REQUEST: transaction & rdsize & srcTID & hop & config_offset(20:13)
-- WRITE-REQUEST: transaction & wrsize & srcTID & hop & config_offset(20:13)
-- READ-RESPONSE: transaction & status & srcTID & hop & reserved(7:0)
-- WRITE-RESPONSE: transaction & status & srcTID & hop & reserved(7:0)
-- PORT-WRITE: transaction & status & reserved(7:0) & hop & reserved(7:0)
transaction <= inboundDat_i(31 downto 28);
size_o <= inboundDat_i(27 downto 24);
status_o <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
hop_o <= inboundDat_i(15 downto 8);
offset_o(20 downto 13) <= inboundDat_i(7 downto 0);
 
packetIndex <= packetIndex + 1;
 
when 4 =>
-- NO-PAYLOAD: config_offset(12:0) & wdptr & rsrv(1:0) & crc(15:0)
-- WITH-PAYLOAD: config_offset(12:0) & wdptr & rsrv(1:0) & double-word0(63:48)
offset_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr_o <= inboundDat_i(18);
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
 
if (ENABLE_READ_REQUEST and (transaction = TTYPE_MAINTENANCE_READ_REQUEST)) then
readRequestComplete <= '1';
elsif (ENABLE_WRITE_RESPONSE and (transaction = TTYPE_MAINTENANCE_WRITE_RESPONSE)) then
writeResponseComplete <= '1';
end if;
end if;
else
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
inboundAck <= '0';
end if;
 
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
-- double-word(47:16)
packetData(31 downto 0) <= inboundDat_i;
memoryWrite <= '0';
packetIndex <= packetIndex + 1;
 
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 =>
-- double-word(15:0) & double-word(63:48)
packetData(47 downto 32) <= inboundDat_i(15 downto 0);
payloadIndex <= payloadIndex + 1;
 
memoryWrite <= '1';
memoryAddress <= std_logic_vector(payloadIndex);
memoryDataIn <= packetData & inboundDat_i(31 downto 16);
 
if (ENABLE_WRITE_REQUEST and (transaction = TTYPE_MAINTENANCE_WRITE_REQUEST)) then
writeRequestComplete <= '1';
elsif (ENABLE_READ_RESPONSE and (transaction = TTYPE_MAINTENANCE_READ_RESPONSE)) then
readResponseComplete <= '1';
elsif (ENABLE_PORT_WRITE and (transaction = TTYPE_MAINTENANCE_PORT_WRITE)) then
-- REMARK: Do this when 2 double words has been received?
portWriteComplete <= '1';
end if;
 
packetIndex <= packetIndex + 1;
 
when others =>
-- There should be no more content in a maintenance packet.
-- Discard.
report "MaintenanceClass: Received unexpected packet content." severity warning;
end case;
else
-- No incoming packet content.
 
-- Make sure there is no write access anymore.
memoryWrite <= '0';
 
-- Check if a packet has been completed.
if ((readRequestComplete = '1') or (writeRequestComplete = '1') or
(readResponseComplete = '1') or (writeResponseComplete = '1')) then
state <= READY;
(readResponseComplete = '1') or (writeResponseComplete = '1') or
(portWriteComplete = '1')) then
-- Packet completed.
busy <= '1';
else
-- No packet completed.
packetIndex <= 0;
memoryAddress <= (others=>'0');
payloadIndex <= (others=>'0');
end if;
end if;
 
when READY =>
else
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
-- Stall any incoming maintenance packet until the current has been
-- processed and wait for the handler of the packet to signal that it
-- has been processed.
---------------------------------------------------------------------
if (done_i = '1') then
busy <= '0';
packetIndex <= 0;
memoryAddress <= (others=>'0');
payloadIndex <= (others=>'0');
readRequestComplete <= '0';
writeRequestComplete <= '0';
readResponseComplete <= '0';
writeResponseComplete <= '0';
state <= RECEIVE_PACKET;
portWriteComplete <= '0';
end if;
when others =>
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Payload content memory.
-----------------------------------------------------------------------------
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>enable,
addressB_i=>payloadIndex_i,
dataB_o=>payload_o);
 
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- RequestClassInbound.
-------------------------------------------------------------------------------
-- REMARK: Extended addresses are not supported yet...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
nreadReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundStall_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RequestClassInbound of RequestClassInbound is
signal busy : std_logic;
signal transaction : std_logic_vector(3 downto 0);
signal complete : std_logic;
signal packetIndex : natural range 0 to 69;
 
signal rdsize : std_logic_vector(3 downto 0);
signal wdptr : std_logic;
 
begin
 
nreadReady_o <= complete and busy;
 
inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"2")) else '0';
 
RequestClass: process(clk, areset_n)
begin
if (areset_n = '0') then
complete <= '0';
transaction <= "0000";
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
dstId_o <= (others=>'0');
srcId_o <= (others=>'0');
tid_o <= (others=>'0');
address_o <= (others=>'0');
 
rdsize <= (others=>'0');
wdptr <= '0';
busy <= '0';
packetIndex <= 0;
elsif (clk'event and clk = '1') then
if (enable = '1') then
if (busy = '0') then
---------------------------------------------------------------------
--
-- This state waits for a new REQUEST class packet, receives it
-- and parses it.
---------------------------------------------------------------------
if ((inboundStb_i = '1') and (inboundAdr_i = x"2")) then
-- New inbound packet content.
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13)
transaction <= inboundDat_i(31 downto 28);
rdsize <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
address_o(28 downto 13) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0)
address_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
address_o(30 downto 29) <= inboundDat_i(17 downto 16);
packetIndex <= packetIndex + 1;
if (transaction = TTYPE_NREAD_TRANSACTION) then
-- An NREAD packet has been completed.
complete <= '1';
end if;
when others =>
-- There should be no more content in a REQUEST.
-- Discard.
report "RequestClass: Received unexpected packet content." severity warning;
end case;
else
-- No incoming packet content.
busy <= complete;
end if;
else
---------------------------------------------------------------------
-- Stall any incoming REQUEST packet until the current has been
-- processed and wait for the handler of the packet to signal that it
-- has been processed.
---------------------------------------------------------------------
if (done_i = '1') then
busy <= '0';
packetIndex <= 0;
complete <= '0';
end if;
end if;
end if;
end if;
end process;
 
end case;
-----------------------------------------------------------------------------
-- Transformation of rdsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
length_o <= "00000";
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (complete = '1') then
if (wdptr = '0') then
case rdsize is
when "0000" =>
length_o <= "00001";
select_o <= "10000000";
when "0001" =>
length_o <= "00001";
select_o <= "01000000";
when "0010" =>
length_o <= "00001";
select_o <= "00100000";
when "0011" =>
length_o <= "00001";
select_o <= "00010000";
when "0100" =>
length_o <= "00001";
select_o <= "11000000";
when "0101" =>
length_o <= "00001";
select_o <= "11100000";
when "0110" =>
length_o <= "00001";
select_o <= "00110000";
when "0111" =>
length_o <= "00001";
select_o <= "11111000";
when "1000" =>
length_o <= "00001";
select_o <= "11110000";
when "1001" =>
length_o <= "00001";
select_o <= "11111100";
when "1010" =>
length_o <= "00001";
select_o <= "11111110";
when "1011" =>
length_o <= "00001";
select_o <= "11111111";
when "1100" =>
length_o <= "00100";
select_o <= "11111111";
when "1101" =>
length_o <= "01100";
select_o <= "11111111";
when "1110" =>
length_o <= "10100";
select_o <= "11111111";
when others =>
length_o <= "11100";
select_o <= "11111111";
end case;
else
case rdsize is
when "0000" =>
length_o <= "00001";
select_o <= "00001000";
when "0001" =>
length_o <= "00001";
select_o <= "00000100";
when "0010" =>
length_o <= "00001";
select_o <= "00000010";
when "0011" =>
length_o <= "00001";
select_o <= "00000001";
when "0100" =>
length_o <= "00001";
select_o <= "00001100";
when "0101" =>
length_o <= "00001";
select_o <= "00000111";
when "0110" =>
length_o <= "00001";
select_o <= "00000011";
when "0111" =>
length_o <= "00001";
select_o <= "00011111";
when "1000" =>
length_o <= "00001";
select_o <= "00001111";
when "1001" =>
length_o <= "00001";
select_o <= "00111111";
when "1010" =>
length_o <= "00001";
select_o <= "01111111";
when "1011" =>
length_o <= "00010";
select_o <= "11111111";
when "1100" =>
length_o <= "01000";
select_o <= "11111111";
when "1101" =>
length_o <= "10000";
select_o <= "11111111";
when "1110" =>
length_o <= "11000";
select_o <= "11111111";
when others =>
length_o <= "00000";
select_o <= "11111111";
end case;
end if;
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;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Add support for extended addresses...
-- length_o is the actual size of the access. A 32 double-word access has length=0.
entity WriteClassInbound is
generic(
ENABLE_NWRITE : boolean := true;
ENABLE_NWRITER : boolean := true;
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
nwriteReady_o : out std_logic;
nwriterReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundStall_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture WriteClassInbound of WriteClassInbound is
signal busy : std_logic;
signal transaction : std_logic_vector(3 downto 0);
signal payloadIndex : unsigned(4 downto 0);
signal packetIndex : natural range 0 to 69;
signal doubleWord : std_logic_vector(63 downto 16);
 
signal nwriteComplete : std_logic;
signal nwriterComplete : std_logic;
 
signal wdptr : std_logic;
signal wrsize : std_logic_vector(3 downto 0);
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataIn : std_logic_vector(63 downto 0);
begin
 
nwriteReady_o <= nwriteComplete and busy;
nwriterReady_o <= nwriterComplete and busy;
 
inboundStall_o <= busy when ((inboundStb_i = '1') and (inboundAdr_i = x"5")) else '0';
 
WriteClass: process(clk, areset_n)
begin
if (areset_n = '0') then
nwriteComplete <= '0';
nwriterComplete <= '0';
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
dstId_o <= (others=>'0');
srcId_o <= (others=>'0');
tid_o <= (others=>'0');
address_o <= (others=>'0');
 
busy <= '0';
transaction <= "0000";
payloadIndex <= (others=>'0');
packetIndex <= 0;
doubleWord <= (others=>'0');
 
wdptr <= '0';
wrsize <= (others=>'0');
memoryWrite <= '0';
memoryAddress <= (others=>'0');
memoryDataIn <= (others=>'0');
elsif (clk'event and clk = '1') then
if (enable = '1') then
if (busy = '0') then
---------------------------------------------------------------------
-- This state waits for a new maintenance packet, receives it
-- and parses it.
---------------------------------------------------------------------
if ((inboundStb_i = '1') and (inboundAdr_i = x"5")) then
-- New inbound packet content.
 
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
dstId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
srcId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & address(28:13)
transaction <= inboundDat_i(31 downto 28);
wrsize <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
address_o(28 downto 13) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48)
address_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
address_o(30 downto 29) <= inboundDat_i(17 downto 16);
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-word(47:16)
doubleWord(47 downto 16) <= inboundDat_i;
memoryWrite <= '0';
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 =>
-- double-word(15:0) & double-word(63:48)
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
payloadIndex <= payloadIndex + 1;
 
memoryWrite <= '1';
memoryAddress <= std_logic_vector(payloadIndex);
memoryDataIn <= doubleWord(63 downto 16) & inboundDat_i(31 downto 16);
if (ENABLE_NWRITE and (transaction = TTYPE_NWRITE_TRANSACTION)) then
nwriteComplete <= '1';
elsif (ENABLE_NWRITER and (transaction = TTYPE_NWRITER_TRANSACTION)) then
nwriterComplete <= '1';
end if;
packetIndex <= packetIndex + 1;
when others =>
-- There should be no more content in an NWRITE/NWRITER request.
-- Discard.
report "WriteClass: Received unexpected packet content." severity warning;
end case;
else
-- No incoming packet content.
 
-- Make sure there is no write access anymore.
memoryWrite <= '0';
 
-- Check if a packet has been completed.
if (nwriteComplete = '1') or (nwriteRComplete = '1') then
-- Packet completed.
busy <= '1';
else
-- No packet completed.
packetIndex <= 0;
payloadIndex <= (others=>'0');
end if;
end if;
else
---------------------------------------------------------------------
-- Stall any incoming write packet until the current has been
-- processed and wait for the handler of the packet to signal that it
-- has been processed.
---------------------------------------------------------------------
if (done_i = '1') then
busy <= '0';
packetIndex <= 0;
payloadIndex <= (others=>'0');
nwriteComplete <= '0';
nwriterComplete <= '0';
end if;
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of rdsize/wrsize into length of access and byte lanes.
-- Transformation of wrsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
size_o <= (others=>'0');
wdptr_o <= '0';
payloadLength_o <= (others=>'0');
length_o <= "00000";
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (readRequestComplete = '1') or (writeRequestComplete = '1') then
size_o <= size;
wdptr_o <= wdptr;
payloadLength_o <= memoryAddress;
elsif (readResponseComplete = '1') then
size_o <= size;
wdptr_o <= wdptr;
payloadLength_o <= memoryAddress;
else
size_o <= size;
wdptr_o <= wdptr;
payloadLength_o <= (others=>'0');
if ((nwriteComplete = '1') or (nwriterComplete = '1')) then
if (wdptr = '0') then
case wrsize is
when "0000" =>
length_o <= "00001";
select_o <= "10000000";
when "0001" =>
length_o <= "00001";
select_o <= "01000000";
when "0010" =>
length_o <= "00001";
select_o <= "00100000";
when "0011" =>
length_o <= "00001";
select_o <= "00010000";
when "0100" =>
length_o <= "00001";
select_o <= "11000000";
when "0101" =>
length_o <= "00001";
select_o <= "11100000";
when "0110" =>
length_o <= "00001";
select_o <= "00110000";
when "0111" =>
length_o <= "00001";
select_o <= "11111000";
when "1000" =>
length_o <= "00001";
select_o <= "11110000";
when "1001" =>
length_o <= "00001";
select_o <= "11111100";
when "1010" =>
length_o <= "00001";
select_o <= "11111110";
when "1011" =>
length_o <= "00001";
select_o <= "11111111";
when others =>
length_o <= std_logic_vector(payloadIndex);
select_o <= "11111111";
end case;
else
case wrsize is
when "0000" =>
length_o <= "00001";
select_o <= "00001000";
when "0001" =>
length_o <= "00001";
select_o <= "00000100";
when "0010" =>
length_o <= "00001";
select_o <= "00000010";
when "0011" =>
length_o <= "00001";
select_o <= "00000001";
when "0100" =>
length_o <= "00001";
select_o <= "00001100";
when "0101" =>
length_o <= "00001";
select_o <= "00000111";
when "0110" =>
length_o <= "00001";
select_o <= "00000011";
when "0111" =>
length_o <= "00001";
select_o <= "00011111";
when "1000" =>
length_o <= "00001";
select_o <= "00001111";
when "1001" =>
length_o <= "00001";
select_o <= "00111111";
when "1010" =>
length_o <= "00001";
select_o <= "01111111";
when others =>
length_o <= std_logic_vector(payloadIndex);
select_o <= "11111111";
end case;
end if;
end if;
end if;
end process;
422,14 → 902,15
-----------------------------------------------------------------------------
-- Payload content memory.
-----------------------------------------------------------------------------
 
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64)
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>enable,
enableB_i=>'1',
addressB_i=>payloadIndex_i,
dataB_o=>payload_o);
 
436,6 → 917,7
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- MaintenanceOutbound.
-------------------------------------------------------------------------------
458,6 → 940,7
readResponseReady_i : in std_logic;
writeResponseReady_i : in std_logic;
portWriteReady_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
475,10 → 958,10
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundAdr_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
outboundStall_i : in std_logic);
end entity;
 
 
485,24 → 968,20
-------------------------------------------------------------------------------
-- Architecture for MaintenanceOutbound.
-------------------------------------------------------------------------------
-- REMARK: use the same variable for status and size internally...
architecture MaintenanceOutbound of MaintenanceOutbound is
type StateType is (WAIT_PACKET,
READ_REQUEST, WRITE_REQUEST,
READ_RESPONSE, WRITE_RESPONSE,
WAIT_COMPLETE, RESPONSE_DONE);
type StateType is (WAIT_PACKET, SEND_PACKET, WAIT_COMPLETE);
signal state : StateType;
signal packetIndex : natural range 0 to 21;
signal header : std_logic_vector(31 downto 0);
signal payload : std_logic_vector(15 downto 0);
signal payloadIndex : std_logic_vector(2 downto 0);
signal payload : std_logic_vector(47 downto 0);
begin
 
-- unused(31:16) | ackId(15:10) | vc(9) | crf(8) | prio(7:6) | tt(5:4) | ftype(3:0).
header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"8";
payloadIndex_o <= payloadIndex;
 
payloadIndex_o <= payloadIndex;
outboundAdr_o <= '1';
MaintenanceResponse: process(clk, areset_n)
begin
513,9 → 992,8
payload <= (others=>'0');
payloadIndex <= (others=>'0');
outboundCyc_o <= '0';
outboundStb_o <= '0';
 
outboundDat_o <= (others=>'0');
done_o <= '0';
elsif (clk'event and clk = '1') then
if (enable = '1') then
524,187 → 1002,288
-------------------------------------------------------------------
--
-------------------------------------------------------------------
outboundStb_o <= '0';
payloadIndex <= (others=>'0');
if (readRequestReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
state <= READ_REQUEST;
elsif (writeRequestReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
state <= WRITE_REQUEST;
elsif (readResponseReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
state <= READ_RESPONSE;
elsif (writeResponseReady_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
state <= WRITE_RESPONSE;
if ((readRequestReady_i = '1') or (writeRequestReady_i = '1') or
(readResponseReady_i = '1') or (writeResponseReady_i = '1') or
(portWriteReady_i = '1')) then
state <= SEND_PACKET;
end if;
 
when READ_REQUEST =>
---------------------------------------------------------------------
-- unused(31:16) | ackId(15:10) | vc(9) | crf(8) | prio(7:6) | tt(5:4) | ftype(3:0).
outboundDat_o <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"8";
packetIndex <= 1;
when SEND_PACKET =>
-------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
-------------------------------------------------------------------
outboundStb_o <= '1';
if (outboundStall_i = '0') then
case (packetIndex) is
when 1 =>
-- dstid
outboundDat_o <= dstid_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
outboundDat_o <= srcid_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & rdsize & srcTID & hop & config_offset(20:13)
outboundDat_o <= "0000" & size_i & tid_i & hop_i & offset_i(20 downto 13);
packetIndex <= packetIndex + 1;
when others =>
-- config_offset(12:0) & wdptr & rsrv & crc(15:0)
outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & x"0000";
packetIndex <= packetIndex + 1;
state <= WAIT_COMPLETE;
end case;
end if;
 
when WRITE_REQUEST =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
case (packetIndex) is
when 1 =>
-- dstid
outboundDat_o <= dstid_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
outboundDat_o <= srcid_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & size & srcTID & hop & config_offset(20:13)
outboundDat_o <= "0001" & size_i & tid_i & hop_i & offset_i(20 downto 13);
-- transaction & status & targetTID & hop & reserved(20:13)
-- transaction & status & reserved(7:0) & hop & reserved(20:13)
if (readRequestReady_i = '1') then
outboundDat_o <= TTYPE_MAINTENANCE_READ_REQUEST & size_i & tid_i & hop_i & offset_i(20 downto 13);
elsif (writeRequestReady_i = '1') then
outboundDat_o <= TTYPE_MAINTENANCE_WRITE_REQUEST & size_i & tid_i & hop_i & offset_i(20 downto 13);
elsif (readResponseReady_i = '1') then
outboundDat_o <= TTYPE_MAINTENANCE_READ_RESPONSE & status_i & tid_i & hop_i & x"00";
elsif (writeResponseReady_i = '1') then
outboundDat_o <= TTYPE_MAINTENANCE_WRITE_RESPONSE & status_i & tid_i & hop_i & x"00";
elsif (portWriteReady_i = '1') then
outboundDat_o <= TTYPE_MAINTENANCE_PORT_WRITE & status_i & x"00" & hop_i & x"00";
end if;
packetIndex <= packetIndex + 1;
when 4 =>
-- config_offset(12:0) & wdptr & rsrv & double-wordN(63:48)
outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & payload_i(63 downto 48);
-- READ-REQUEST: config_offset(12:0) & wdptr & rsrv & crc(15:0)
-- WRITE-REQUEST: config_offset(12:0) & wdptr & rsrv & double-wordN(63:48)
-- READ-RESPONSE: reserved(15:0) & double-wordN(63:48)
-- WRITE-RESPONSE: reserved(15:0) & crc(15:0)
-- PORT-WRITE: reserved(15:0) & crc(15:0)
if (readRequestReady_i = '1') then
outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & payload_i(63 downto 48);
state <= WAIT_COMPLETE;
elsif (writeRequestReady_i = '1') then
outboundDat_o <= offset_i(12 downto 0) & wdptr_i & "00" & payload_i(63 downto 48);
elsif (readResponseReady_i = '1') then
outboundDat_o <= x"0000" & payload_i(63 downto 48);
elsif (writeResponseReady_i = '1') then
outboundDat_o <= x"0000" & payload_i(63 downto 48);
state <= WAIT_COMPLETE;
elsif (portWriteReady_i = '1') then
outboundDat_o <= x"0000" & payload_i(63 downto 48);
end if;
 
payload <= payload_i(47 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
-- double-wordN(47:16)
outboundDat_o <= payload_i(47 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
outboundDat_o <= payload(47 downto 16);
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 =>
-- double-wordN(15:0) & double-wordN(63:48)
outboundDat_o <= payload & payload_i(63 downto 48);
packetIndex <= packetIndex + 1;
outboundDat_o <= payload(15 downto 0) & payload_i(63 downto 48);
 
payload <= payload_i(47 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
if (payloadIndex = payloadLength_i) then
state <= WAIT_COMPLETE;
end if;
 
packetIndex <= packetIndex + 1;
when others =>
-- double-wordN(15:0) & double-wordN(63:48)
outboundDat_o <= payload & x"0000";
outboundDat_o <= payload(15 downto 0) & x"0000";
state <= WAIT_COMPLETE;
end case;
end if;
 
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
outboundStb_o <= '0';
if ((readRequestReady_i = '0') and (writeRequestReady_i = '0') and
(readResponseReady_i = '0') and (writeResponseReady_i = '0') and
(portWriteReady_i = '0')) then
state <= WAIT_PACKET;
done_o <= '0';
else
done_o <= '1';
end if;
when READ_RESPONSE =>
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
state <= WAIT_PACKET;
end case;
end if;
end if;
end process;
 
end architecture;
 
 
 
-------------------------------------------------------------------------------
-- ResponseClassOutbound
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
doneNoPayloadReady_i : in std_logic;
doneWithPayloadReady_i : in std_logic;
errorReady_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
tt_i : in std_logic_vector(1 downto 0);
dstid_i : in std_logic_vector(31 downto 0);
srcid_i : in std_logic_vector(31 downto 0);
tid_i : in std_logic_vector(7 downto 0);
payloadLength_i : in std_logic_vector(4 downto 0);
payloadIndex_o : out std_logic_vector(4 downto 0);
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundStb_o : out std_logic;
outboundAdr_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundStall_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture ResponseClassOutbound of ResponseClassOutbound is
type StateType is (WAIT_PACKET, SEND_PACKET, WAIT_COMPLETE);
signal state : StateType;
signal packetIndex : natural range 0 to 68;
 
signal payloadIndex : std_logic_vector(4 downto 0);
signal payload : std_logic_vector(47 downto 0);
begin
 
payloadIndex_o <= payloadIndex;
outboundAdr_o <= '1';
Response: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= WAIT_PACKET;
packetIndex <= 0;
 
payloadIndex <= (others=>'0');
payload <= (others=>'0');
outboundStb_o <= '0';
outboundDat_o <= (others=>'0');
done_o <= '0';
elsif (clk'event and clk = '1') then
if (enable = '1') then
case state is
when WAIT_PACKET =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
outboundStb_o <= '0';
payloadIndex <= (others=>'0');
if ((doneNoPayloadReady_i = '1') or
(doneWithPayloadReady_i = '1') or
(errorReady_i = '1')) then
state <= SEND_PACKET;
end if;
outboundDat_o <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d";
packetIndex <= 1;
 
when SEND_PACKET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
outboundStb_o <= '1';
if (outboundStall_i = '0') then
case (packetIndex) is
when 1 =>
-- dstid
outboundDat_o <= dstid_i;
outboundDat_o <= dstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
outboundDat_o <= srcid_i;
outboundDat_o <= srcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
outboundDat_o <= "0010" & status_i & tid_i & hop_i & x"00";
-- transaction & status & targetTID & double-word0(63:48)
if (doneNoPayloadReady_i = '1') then
outboundDat_o <= TTYPE_RESPONSE_NO_PAYLOAD & "0000" & tid_i & x"0000";
state <= WAIT_COMPLETE;
elsif (doneWithPayloadReady_i = '1') then
outboundDat_o <= TTYPE_RESPONSE_WITH_PAYLOAD & "0000" & tid_i & payload_i(63 downto 48);
elsif (errorReady_i = '1') then
outboundDat_o <= TTYPE_RESPONSE_NO_PAYLOAD & "0111" & tid_i & x"0000";
state <= WAIT_COMPLETE;
end if;
 
payload <= payload_i(47 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
packetIndex <= packetIndex + 1;
when 4 =>
-- reserved(15:0) & double-wordN(63:48)
outboundDat_o <= x"0000" & payload_i(63 downto 48);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 =>
when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
-- double-wordN(47:16)
outboundDat_o <= payload_i(47 downto 16);
payload <= payload_i(15 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
outboundDat_o <= payload(47 downto 16);
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 =>
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-wordN(15:0) & double-wordN(63:48)
outboundDat_o <= payload & payload_i(63 downto 48);
packetIndex <= packetIndex + 1;
outboundDat_o <= payload(15 downto 0) & payload_i(63 downto 48);
 
payload <= payload_i(47 downto 0);
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
if (payloadIndex = payloadLength_i) then
state <= WAIT_COMPLETE;
end if;
packetIndex <= packetIndex + 1;
when others =>
-- double-wordN(15:0) & double-wordN(63:48)
outboundDat_o <= payload & x"0000";
state <= WAIT_COMPLETE;
-- Unallowed response length.
-- Dont do anything.
end case;
end if;
when WRITE_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
case (packetIndex) is
when 1 =>
-- dstid
outboundDat_o <= dstid_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
outboundDat_o <= srcid_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & hop & reserved(7:0)
outboundDat_o <= "0011" & status_i & tid_i & hop_i & x"00";
packetIndex <= packetIndex + 1;
when others =>
-- reserved(15:0) & crc(15:0)
outboundDat_o <= x"00000000";
packetIndex <= packetIndex + 1;
state <= WAIT_COMPLETE;
end case;
end if;
 
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (outboundAck_i = '1') then
outboundCyc_o <= '0';
outboundStb_o <= '0';
state <= RESPONSE_DONE;
end if;
when RESPONSE_DONE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if ((readRequestReady_i = '0') and (writeRequestReady_i = '0') and
(readResponseReady_i = '0') and (writeResponseReady_i = '0')) then
outboundStb_o <= '0';
if ((doneNoPayloadReady_i = '0') and (doneWithPayloadReady_i = '0') and
(errorReady_i = '0')) then
state <= WAIT_PACKET;
done_o <= '0';
else
/branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd
10,13 → 10,8
-- NWRITE, NWRITER and NREAD are currently supported.
--
-- To Do:
-- - Move packet handlers to RioLogicalPackets and make them symetrical.
-- - Add support for addressing to implementation defined config space by
-- adding interface to top entity.
-- - Set the stb_o to '0' in between read accesses to conform better to a
-- block transfer in the Wishbone standard.
-- - Clean up cyc-signals, only stb-signals are needed (between
-- RioLogicalCommon and the packet handlers).
-- - Add support for the lock_o to be sure to transfer all the packet
-- content atomically?
-- - Add support for EXTENDED_ADDRESS.
23,9 → 18,6
-- - Use the baseDeviceId when sending packets? Currently, all responses
-- are sent with destination<->source exchanged so the baseDeviceId is not
-- needed.
-- - Support inbound data with full bandwidth, not just half, applies to
-- RioLogicalCommon and the packet handlers.
-- - Move the packet handlers to seperate files.
-- - Increase the priority of the response-packet when sent?
-- - Implement error indications if erronous packets are received.
-- - Implement error indications if err_i is received on the Wishbone bus.
68,7 → 60,7
-------------------------------------------------------------------------------
-- RioWbBridge.
-- This block acts as an RapidIO endpoint and converts packets into Wishbone
-- accesses.
-- accesses. The bridge is acting as a Wishbone-slave only.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
119,108 → 111,17
-- Architecture for RioWbBridge.
-------------------------------------------------------------------------------
architecture RioWbBridgeImpl of RioWbBridge is
 
component RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
end component;
component WriteClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_o : out std_logic;
responseNeeded_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadRead_i : in std_logic;
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
end component;
 
component ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
tt_i : in std_logic_vector(1 downto 0);
dstid_i : in std_logic_vector(31 downto 0);
srcid_i : in std_logic_vector(31 downto 0);
tid_i : in std_logic_vector(7 downto 0);
error_i : in std_logic;
payloadPresent_i : in std_logic;
payloadLength_i : in std_logic_vector(4 downto 0);
payloadWrite_i : in std_logic;
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
end component;
 
constant PORTS : natural := 2;
 
type StateType is (IDLE,
REQUEST_CLASS, REQUEST_CLASS_RESPONSE,
WRITE_CLASS, WRITE_CLASS_ACCESS, WRITE_CLASS_ACK, WRITE_CLASS_RESPONSE);
REQUEST_CLASS, REQUEST_CLASS_WAIT, REQUEST_CLASS_NEXT,
WRITE_CLASS, WRITE_CLASS_WAIT, WRITE_CLASS_NEXT,
RESPONSE_DONE_NO_PAYLOAD, RESPONSE_DONE_WITH_PAYLOAD,
RESPONSE_ERROR, RESPONSE_DONE);
signal state : StateType;
signal adr : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
signal datOut : std_logic_vector(63 downto 0);
 
signal payloadUpdate : std_logic;
signal payloadIndex : std_logic_vector(4 downto 0);
signal requestReady : std_logic;
signal requestVc : std_logic;
signal requestCrf : std_logic;
233,10 → 134,10
signal requestLength : std_logic_vector(4 downto 0);
signal requestSelect : std_logic_vector(7 downto 0);
signal requestDone : std_logic;
signal requestAck : std_logic;
signal requestStall : std_logic;
 
signal writeReady : std_logic;
signal writeResponse : std_logic;
signal writeNoResponseReady : std_logic;
signal writeWithResponseReady : std_logic;
signal writeVc : std_logic;
signal writeCrf : std_logic;
signal writePrio : std_logic_vector(1 downto 0);
245,13 → 146,16
signal writeSrcId : std_logic_vector(31 downto 0);
signal writeTid : std_logic_vector(7 downto 0);
signal writeAddress : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
signal writeLength : std_logic_vector(4 downto 0);
signal writePayloadLength : std_logic_vector(4 downto 0);
signal writePayloadIndex : std_logic_vector(4 downto 0);
signal writeSelect : std_logic_vector(7 downto 0);
signal writePayload : std_logic_vector(63 downto 0);
signal writeDone : std_logic;
signal writeAck : std_logic;
signal writeStall : std_logic;
 
signal responseReady : std_logic;
signal responseDoneNoPayloadReady : std_logic;
signal responseDoneWithPayloadReady : std_logic;
signal responseErrorReady : std_logic;
signal responseVc : std_logic;
signal responseCrf : std_logic;
signal responsePrio : std_logic_vector(1 downto 0);
259,36 → 163,35
signal responseDstId : std_logic_vector(31 downto 0);
signal responseSrcId : std_logic_vector(31 downto 0);
signal responseTid : std_logic_vector(7 downto 0);
signal responseError : std_logic;
signal responsePayloadPresent : std_logic;
signal responsePayloadIndex : std_logic_vector(4 downto 0);
signal responsePayload : std_logic_vector(63 downto 0);
signal responseDone : std_logic;
 
signal readRequestInbound : std_logic;
signal writeRequestInbound : std_logic;
signal vcInbound : std_logic;
signal crfInbound : std_logic;
signal prioInbound : std_logic_vector(1 downto 0);
signal ttInbound : std_logic_vector(1 downto 0);
signal dstIdInbound : std_logic_vector(31 downto 0);
signal srcIdInbound : std_logic_vector(31 downto 0);
signal sizeInbound : std_logic_vector(3 downto 0);
signal tidInbound : std_logic_vector(7 downto 0);
signal offsetInbound : std_logic_vector(20 downto 0);
signal wdptrInbound : std_logic;
signal payloadLengthInbound : std_logic_vector(2 downto 0);
signal payloadInbound : std_logic_vector(63 downto 0);
signal maintReadRequestReady : std_logic;
signal maintWriteRequestReady : std_logic;
signal maintVcInbound : std_logic;
signal maintCrfInbound : std_logic;
signal maintPrioInbound : std_logic_vector(1 downto 0);
signal maintTtInbound : std_logic_vector(1 downto 0);
signal maintDstIdInbound : std_logic_vector(31 downto 0);
signal maintSrcIdInbound : std_logic_vector(31 downto 0);
signal maintSizeInbound : std_logic_vector(3 downto 0);
signal maintTidInbound : std_logic_vector(7 downto 0);
signal maintOffsetInbound : std_logic_vector(20 downto 0);
signal maintWdptrInbound : std_logic;
signal maintPayloadLengthInbound : std_logic_vector(2 downto 0);
signal maintPayloadIndexInbound : std_logic_vector(2 downto 0);
signal maintPayloadInbound : std_logic_vector(63 downto 0);
signal maintDoneInbound : std_logic;
signal maintStall : std_logic;
 
signal readResponseMaint : std_logic;
signal writeResponseMaint : std_logic;
signal statusMaint : std_logic_vector(3 downto 0);
signal payloadLengthMaint : std_logic_vector(2 downto 0);
signal payloadIndexMaint : std_logic_vector(2 downto 0);
signal payloadMaint : std_logic_vector(63 downto 0);
signal doneMaint : std_logic;
signal payloadIndexOutbound : std_logic_vector(2 downto 0);
signal doneOutbound : std_logic;
signal maintReadResponseReady : std_logic;
signal maintWriteResponseReady : std_logic;
signal maintStatusOutbound : std_logic_vector(3 downto 0);
signal maintPayloadLengthOutbound : std_logic_vector(2 downto 0);
signal maintPayloadIndexOutbound : std_logic_vector(2 downto 0);
signal maintPayloadOutbound : std_logic_vector(63 downto 0);
signal maintDoneOutbound : std_logic;
 
signal configStb : std_logic;
signal configWe : std_logic;
297,34 → 200,35
signal configDatWrite : std_logic_vector(31 downto 0);
signal configDatRead : std_logic_vector(31 downto 0);
signal configAck : std_logic;
signal maintenanceAck : std_logic;
signal inboundCyc : std_logic;
signal inboundStb : std_logic;
signal inboundAdr : std_logic_vector(7 downto 0);
signal inboundAdr : std_logic_vector(3 downto 0);
signal inboundDat : std_logic_vector(31 downto 0);
signal inboundAck : std_logic;
signal inboundStall : std_logic;
 
signal outboundCyc : std_logic_vector(PORTS-1 downto 0);
signal outboundStb : std_logic_vector(PORTS-1 downto 0);
signal outboundAdr : std_logic_vector(PORTS-1 downto 0);
signal outboundDat : std_logic_vector(32*PORTS-1 downto 0);
signal outboundAck : std_logic_vector(PORTS-1 downto 0);
signal outboundStall : std_logic_vector(PORTS-1 downto 0);
 
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataIn : std_logic_vector(63 downto 0);
begin
 
responseVc <= requestVc when (responsePayloadPresent = '1') else writeVc;
responseCrf <= requestCrf when (responsePayloadPresent = '1') else writeCrf;
responsePrio <= requestPrio when (responsePayloadPresent = '1') else writePrio;
responseTt <= requestTt when (responsePayloadPresent = '1') else writeTt;
responseDstId <= requestSrcId when (responsePayloadPresent = '1') else writeSrcId;
responseSrcId <= requestDstId when (responsePayloadPresent = '1') else writeDstId;
responseTid <= requestTid when (responsePayloadPresent = '1') else writeTid;
responseVc <= requestVc when (requestReady = '1') else writeVc;
responseCrf <= requestCrf when (requestReady = '1') else writeCrf;
responsePrio <= requestPrio when (requestReady = '1') else writePrio;
responseTt <= requestTt when (requestReady = '1') else writeTt;
responseDstId <= requestSrcId when (requestReady = '1') else writeSrcId;
responseSrcId <= requestDstId when (requestReady = '1') else writeDstId;
responseTid <= requestTid when (requestReady = '1') else writeTid;
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
adr_o <= adr;
dat_o <= datOut;
Bridge: process(clk, areset_n)
begin
333,53 → 237,38
stb_o <= '0';
we_o <= '0';
adr <= (others=>'0');
datOut <= (others=>'0');
dat_o <= (others=>'0');
 
payloadUpdate <= '0';
payloadIndex <= (others=>'0');
writePayloadIndex <= (others=>'0');
requestDone <= '0';
writeDone <= '0';
responseReady <= '0';
responseError <= '0';
responsePayloadPresent <= '0';
responsePayload <= (others=>'0');
responseDoneNoPayloadReady <= '0';
responseDoneWithPayloadReady <= '0';
responseErrorReady <= '0';
memoryWrite <= '0';
memoryAddress <= (others=>'0');
memoryDataIn <= (others=>'0');
elsif (clk'event and clk = '1') then
if (enable = '1') then
requestDone <= '0';
writeDone <= '0';
responseReady <= '0';
payloadUpdate <= '0';
if (payloadUpdate = '1') then
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
end if;
case state is
when IDLE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
requestDone <= '0';
writeDone <= '0';
responseDoneNoPayloadReady <= '0';
responseDoneWithPayloadReady <= '0';
responseErrorReady <= '0';
 
writePayloadIndex <= (others=>'0');
if (requestReady = '1') then
cyc_o <= '1';
stb_o <= '1';
we_o <= '0';
adr <= requestAddress;
sel_o <= requestSelect;
payloadIndex <= (others=>'0');
responsePayloadPresent <= '1';
state <= REQUEST_CLASS;
elsif (writeReady = '1') then
adr <= writeAddress;
 
payloadUpdate <= '1';
payloadIndex <= (others=>'0');
responsePayloadPresent <= '0';
elsif (writeNoResponseReady = '1') or (writeWithResponseReady = '1') then
state <= WRITE_CLASS;
end if;
 
387,32 → 276,52
---------------------------------------------------------------------
--
---------------------------------------------------------------------
cyc_o <= '1';
stb_o <= '1';
we_o <= '0';
adr <= requestAddress;
sel_o <= requestSelect;
 
memoryAddress <= writePayloadIndex;
writePayloadIndex <= std_logic_vector(unsigned(writePayloadIndex) + 1);
 
state <= REQUEST_CLASS_WAIT;
when REQUEST_CLASS_WAIT =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (ack_i = '1') then
-- Note that responsePayloadIndex is updated after the write has been made.
payloadUpdate <= '1';
responsePayload <= dat_i;
adr <= std_logic_vector(unsigned(adr) + 1);
 
if (payloadIndex = requestLength) then
requestDone <= '1';
if (writePayloadIndex = requestLength) then
cyc_o <= '0';
stb_o <= '0';
state <= REQUEST_CLASS_RESPONSE;
end if;
-- elsif(err_i = '1') then
-- REMARK: Implement error indication from wb-bus...
stb_o <= '0';
 
memoryWrite <= '1';
memoryDataIn <= dat_i;
 
state <= REQUEST_CLASS_NEXT;
elsif (err_i = '1') then
cyc_o <= '0';
stb_o <= '0';
state <= RESPONSE_ERROR;
end if;
 
when REQUEST_CLASS_RESPONSE =>
when REQUEST_CLASS_NEXT =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
responseReady <= '0';
state <= IDLE;
memoryWrite <= '0';
memoryAddress <= writePayloadIndex;
writePayloadIndex <= std_logic_vector(unsigned(writePayloadIndex) + 1);
 
adr <= std_logic_vector(unsigned(adr) + 1);
if (writePayloadIndex = requestLength) then
state <= RESPONSE_DONE_WITH_PAYLOAD;
else
responseReady <= '1';
stb_o <= '1';
state <= REQUEST_CLASS_WAIT;
end if;
 
when WRITE_CLASS =>
419,50 → 328,97
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= WRITE_CLASS_ACCESS;
 
when WRITE_CLASS_ACCESS =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
cyc_o <= '1';
stb_o <= '1';
we_o <= '1';
adr <= writeAddress;
sel_o <= writeSelect;
datOut <= writePayload;
payloadUpdate <= '1';
dat_o <= writePayload;
 
state <= WRITE_CLASS_ACK;
writePayloadIndex <= std_logic_vector(unsigned(writePayloadIndex) + 1);
state <= WRITE_CLASS_WAIT;
 
when WRITE_CLASS_ACK =>
when WRITE_CLASS_WAIT =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (ack_i = '1') then
adr <= std_logic_vector(unsigned(adr) + 1);
if (writePayloadIndex = writePayloadLength) then
cyc_o <= '0';
end if;
stb_o <= '0';
if (unsigned(payloadIndex) /= (unsigned(writeLength)+2)) then
stb_o <= '0';
state <= WRITE_CLASS_ACCESS;
state <= WRITE_CLASS_NEXT;
elsif (err_i = '1') then
writeDone <= '1';
cyc_o <= '0';
stb_o <= '0';
state <= RESPONSE_ERROR;
end if;
 
when WRITE_CLASS_NEXT =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
adr <= std_logic_vector(unsigned(adr) + 1);
dat_o <= writePayload;
writePayloadIndex <= std_logic_vector(unsigned(writePayloadIndex) + 1);
if (writePayloadIndex = writePayloadLength) then
if (writeWithResponseReady = '1') then
state <= RESPONSE_DONE_NO_PAYLOAD;
else
writeDone <= '1';
cyc_o <= '0';
stb_o <= '0';
state <= WRITE_CLASS_RESPONSE;
state <= RESPONSE_DONE;
end if;
else
stb_o <= '1';
state <= WRITE_CLASS_WAIT;
end if;
 
when RESPONSE_DONE_NO_PAYLOAD =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') then
writeDone <= '1';
responseDoneNoPayloadReady <= '0';
state <= RESPONSE_DONE;
else
responseDoneNoPayloadReady <= '1';
end if;
 
when WRITE_CLASS_RESPONSE =>
when RESPONSE_DONE_WITH_PAYLOAD =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (responseDone = '1') or (writeResponse = '0') then
responseReady <= '0';
state <= IDLE;
if (responseDone = '1') then
requestDone <= '1';
responseDoneWithPayloadReady <= '0';
state <= RESPONSE_DONE;
else
responseReady <= '1';
responseDoneWithPayloadReady <= '1';
end if;
 
when RESPONSE_ERROR =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
-- REMARK: Must indicate that the previous frame is done also.
if (responseDone = '1') then
responseErrorReady <= '0';
state <= RESPONSE_DONE;
else
responseErrorReady <= '1';
end if;
 
when RESPONSE_DONE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
state <= IDLE;
when others =>
 
end case;
470,10 → 426,54
end if;
end process;
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>responseDoneWithPayloadReady,
addressB_i=>responsePayloadIndex,
dataB_o=>responsePayload);
-----------------------------------------------------------------------------
-- Packet handlers.
-- Inbound packet processing.
-----------------------------------------------------------------------------
 
InboundMaintenance: MaintenanceInbound
generic map(
ENABLE_READ_RESPONSE=>false,
ENABLE_WRITE_RESPONSE=>false,
ENABLE_PORT_WRITE=>false)
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_o=>maintReadRequestReady,
writeRequestReady_o=>maintWriteRequestReady,
readResponseReady_o=>open,
writeResponseReady_o=>open,
portWriteReady_o=>open,
vc_o=>maintVcInbound,
crf_o=>maintCrfInbound,
prio_o=>maintPrioInbound,
tt_o=>maintTtInbound,
dstid_o=>maintDstIdInbound,
srcid_o=>maintSrcIdInbound,
size_o=>maintSizeInbound,
status_o=>open,
tid_o=>maintTidInbound,
hop_o=>open,
offset_o=>maintOffsetInbound,
wdptr_o=>maintWdptrInbound,
payloadLength_o=>maintPayloadLengthInbound,
payloadIndex_i=>maintPayloadIndexInbound,
payload_o=>maintPayloadInbound,
done_i=>maintDoneInbound,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundStall_o=>maintStall);
 
RequestClassInboundInst: RequestClassInbound
generic map(
EXTENDED_ADDRESS=>EXTENDED_ADDRESS)
481,7 → 481,7
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_o=>requestReady,
nreadReady_o=>requestReady,
vc_o=>requestVc,
crf_o=>requestCrf,
prio_o=>requestPrio,
493,11 → 493,10
length_o=>requestLength,
select_o=>requestSelect,
done_i=>requestDone,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>requestAck);
inboundStall_o=>requestStall);
 
WriteClassInboundInst: WriteClassInbound
generic map(
506,8 → 505,8
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_o=>writeReady,
responseNeeded_o=>writeResponse,
nwriteReady_o=>writeNoResponseReady,
nwriterReady_o=>writeWithResponseReady,
vc_o=>writeVc,
crf_o=>writeCrf,
prio_o=>writePrio,
516,24 → 515,56
srcId_o=>writeSrcId,
tid_o=>writeTid,
address_o=>writeAddress,
length_o=>writeLength,
length_o=>writePayloadLength,
select_o=>writeSelect,
payloadRead_i=>payloadUpdate,
payloadIndex_i=>payloadIndex,
payloadIndex_i=>writePayloadIndex,
payload_o=>writePayload,
done_i=>writeDone,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>writeAck);
inboundStall_o=>writeStall);
 
-----------------------------------------------------------------------------
-- Outbound packet processing.
-----------------------------------------------------------------------------
OutboundMaintenance: MaintenanceOutbound
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>'0',
writeRequestReady_i=>'0',
readResponseReady_i=>maintReadResponseReady,
writeResponseReady_i=>maintWriteResponseReady,
portWriteReady_i=>'0',
vc_i=>maintVcInbound,
crf_i=>maintCrfInbound,
prio_i=>maintPrioInbound,
tt_i=>maintTtInbound,
dstid_i=>maintSrcIdInbound,
srcid_i=>maintDstIdInbound,
size_i=>(others=>'0'),
status_i=>maintStatusOutbound,
tid_i=>maintTidInbound,
hop_i=>x"ff",
offset_i=>(others=>'0'),
wdptr_i=>'0',
payloadLength_i=>maintPayloadLengthOutbound,
payloadIndex_o=>maintPayloadIndexOutbound,
payload_i=>maintPayloadOutbound,
done_o=>maintDoneOutbound,
outboundStb_o=>outboundStb(1),
outboundAdr_o=>outboundAdr(1),
outboundDat_o=>outboundDat(63 downto 32),
outboundStall_i=>outboundStall(1));
 
ResponseClassOutboundInst: ResponseClassOutbound
port map(
clk=>clk,
areset_n=>areset_n,
enable=>enable,
ready_i=>responseReady,
doneNoPayloadReady_i=>responseDoneNoPayloadReady,
doneWithPayloadReady_i=>responseDoneWithPayloadReady,
errorReady_i=>responseErrorReady,
vc_i=>responseVc,
crf_i=>responseCrf,
prio_i=>responsePrio,
541,111 → 572,20
dstid_i=>responseDstId,
srcid_i=>responseSrcId,
tid_i=>responseTid,
error_i=>responseError,
payloadPresent_i=>responsePayloadPresent,
payloadLength_i=>requestLength,
payloadWrite_i=>payloadUpdate,
payloadIndex_i=>payloadIndex,
payloadIndex_o=>responsePayloadIndex,
payload_i=>responsePayload,
done_o=>responseDone,
outboundCyc_o=>outboundCyc(0),
outboundStb_o=>outboundStb(0),
outboundAdr_o=>outboundAdr(0),
outboundDat_o=>outboundDat(31 downto 0),
outboundAck_i=>outboundAck(0));
outboundStall_i=>outboundStall(0));
 
-----------------------------------------------------------------------------
-- Maintenance packet processing.
-----------------------------------------------------------------------------
InboundMaintenance: MaintenanceInbound
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_o=>readRequestInbound,
writeRequestReady_o=>writeRequestInbound,
readResponseReady_o=>open,
writeResponseReady_o=>open,
portWriteReady_o=>open,
vc_o=>vcInbound,
crf_o=>crfInbound,
prio_o=>prioInbound,
tt_o=>ttInbound,
dstid_o=>dstIdInbound,
srcid_o=>srcIdInbound,
size_o=>sizeInbound,
status_o=>open,
tid_o=>tidInbound,
hop_o=>open,
offset_o=>offsetInbound,
wdptr_o=>wdptrInbound,
payloadLength_o=>payloadLengthInbound,
payloadIndex_i=>payloadIndexMaint,
payload_o=>payloadInbound,
done_i=>doneMaint,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>maintenanceAck);
 
OutboundMaintenance: MaintenanceOutbound
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>'0',
writeRequestReady_i=>'0',
readResponseReady_i=>readResponseMaint,
writeResponseReady_i=>writeResponseMaint,
portWriteReady_i=>'0',
vc_i=>vcInbound,
crf_i=>crfInbound,
prio_i=>prioInbound,
tt_i=>ttInbound,
dstid_i=>srcIdInbound,
srcid_i=>dstIdInbound,
size_i=>(others=>'0'),
status_i=>statusMaint,
tid_i=>tidInbound,
hop_i=>x"ff",
offset_i=>(others=>'0'),
wdptr_i=>'0',
payloadLength_i=>payloadLengthMaint,
payloadIndex_o=>payloadIndexOutbound,
payload_i=>payloadMaint,
done_o=>doneOutbound,
outboundCyc_o=>outboundCyc(1),
outboundStb_o=>outboundStb(1),
outboundDat_o=>outboundDat(63 downto 32),
outboundAck_i=>outboundAck(1));
 
MaintenanceBridge: RioLogicalMaintenance
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>readRequestInbound,
writeRequestReady_i=>writeRequestInbound,
size_i=>sizeInbound,
offset_i=>offsetInbound,
wdptr_i=>wdptrInbound,
payloadLength_i=>payloadLengthInbound,
payloadIndex_o=>payloadIndexMaint,
payload_i=>payloadInbound,
done_o=>doneMaint,
readResponseReady_o=>readResponseMaint,
writeResponseReady_o=>writeResponseMaint,
status_o=>statusMaint,
payloadLength_o=>payloadLengthMaint,
payloadIndex_i=>payloadIndexOutbound,
payload_o=>payloadMaint,
done_i=>doneOutbound,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAdr,
configDat_o=>configDatWrite,
configDat_i=>configDatRead,
configAck_i=>configAck);
 
-----------------------------------------------------------------------------
-- Common interface toward the packet queues.
-----------------------------------------------------------------------------
inboundAck <= requestAck or writeAck or maintenanceAck;
inboundStall <= requestStall or writeStall or maintStall;
RioLogicalCommonInst: RioLogicalCommon
generic map(PORTS=>PORTS)
port map(
662,20 → 602,46
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentData_o=>writeContentData_o,
inboundCyc_o=>inboundCyc,
inboundStb_o=>inboundStb,
inboundAdr_o=>inboundAdr,
inboundDat_o=>inboundDat,
inboundAck_i=>inboundAck,
outboundCyc_i=>outboundCyc,
inboundStall_i=>inboundStall,
outboundStb_i=>outboundStb,
outboundAdr_i=>outboundAdr,
outboundDat_i=>outboundDat,
outboundAck_o=>outboundAck);
outboundStall_o=>outboundStall);
 
-----------------------------------------------------------------------------
-- Configuration memory.
-----------------------------------------------------------------------------
MaintenanceBridge: RioLogicalMaintenance
port map(
clk=>clk, areset_n=>areset_n, enable=>enable,
readRequestReady_i=>maintReadRequestReady,
writeRequestReady_i=>maintWriteRequestReady,
size_i=>maintSizeInbound,
offset_i=>maintOffsetInbound,
wdptr_i=>maintWdptrInbound,
payloadLength_i=>maintPayloadLengthInbound,
payloadIndex_o=>maintPayloadIndexInbound,
payload_i=>maintPayloadInbound,
done_o=>maintDoneInbound,
readResponseReady_o=>maintReadResponseReady,
writeResponseReady_o=>maintWriteResponseReady,
status_o=>maintStatusOutbound,
payloadLength_o=>maintPayloadLengthOutbound,
payloadIndex_i=>maintPayloadIndexOutbound,
payload_o=>maintPayloadOutbound,
done_i=>maintDoneOutbound,
configStb_o=>configStb,
configWe_o=>configWe,
configAdr_o=>configAdr,
configDat_o=>configDatWrite,
configDat_i=>configDatRead,
configAck_i=>configAck);
 
configAdrByte <= configAdr & "00";
memoryConfig : process(clk, areset_n)
variable componentTag : std_logic_vector(31 downto 0);
variable hostBaseDeviceIdLocked : std_logic;
818,814 → 784,3
end process;
 
end architecture;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
-- REMARK: Extended addresses are not supported yet...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture RequestClassInbound of RequestClassInbound is
type StateType is (RECEIVE_PACKET, READY);
signal state : StateType;
 
signal rdsize : std_logic_vector(3 downto 0);
signal wdptr : std_logic;
 
signal inboundAck : std_logic;
signal complete : std_logic;
 
signal packetIndex : natural range 0 to 69;
 
begin
 
inboundAck_o <= inboundAck;
 
ready_o <= complete when (state = READY) else '0';
 
RequestClass: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= RECEIVE_PACKET;
rdsize <= (others=>'0');
wdptr <= '0';
inboundAck <= '0';
complete <= '0';
packetIndex <= 0;
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
dstId_o <= (others=>'0');
srcId_o <= (others=>'0');
tid_o <= (others=>'0');
address_o <= (others=>'0');
elsif (clk'event and clk = '1') then
case state is
when RECEIVE_PACKET =>
---------------------------------------------------------------------
-- This state waits for a new REQUEST class packet, receives it
-- and parses it.
---------------------------------------------------------------------
if (inboundCyc_i = '1') then
if (inboundAck = '0') then
if (inboundStb_i = '1') then
if (inboundAdr_i = x"24") then
-------------------------------------------------------------
-- NREAD packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- dstid
dstId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcid
srcId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13)
rdsize <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
address_o(28 downto 13) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0)
address_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
address_o(30 downto 29) <= inboundDat_i(17 downto 16);
packetIndex <= packetIndex + 1;
complete <= '1';
when others =>
-- There should be no more content in an NREAD.
-- Discard.
end case;
inboundAck <= '1';
end if;
end if;
else
inboundAck <= '0';
end if;
else
if (complete = '1') then
state <= READY;
end if;
packetIndex <= 0;
end if;
 
when READY =>
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
---------------------------------------------------------------------
if (done_i = '1') then
complete <= '0';
state <= RECEIVE_PACKET;
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of rdsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
length_o <= "00000";
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (complete = '1') then
if (wdptr = '0') then
case rdsize is
when "0000" =>
length_o <= "00000";
select_o <= "10000000";
when "0001" =>
length_o <= "00000";
select_o <= "01000000";
when "0010" =>
length_o <= "00000";
select_o <= "00100000";
when "0011" =>
length_o <= "00000";
select_o <= "00010000";
when "0100" =>
length_o <= "00000";
select_o <= "11000000";
when "0101" =>
length_o <= "00000";
select_o <= "11100000";
when "0110" =>
length_o <= "00000";
select_o <= "00110000";
when "0111" =>
length_o <= "00000";
select_o <= "11111000";
when "1000" =>
length_o <= "00000";
select_o <= "11110000";
when "1001" =>
length_o <= "00000";
select_o <= "11111100";
when "1010" =>
length_o <= "00000";
select_o <= "11111110";
when "1011" =>
length_o <= "00000";
select_o <= "11111111";
when "1100" =>
length_o <= "00011";
select_o <= "11111111";
when "1101" =>
length_o <= "01011";
select_o <= "11111111";
when "1110" =>
length_o <= "10011";
select_o <= "11111111";
when others =>
length_o <= "11011";
select_o <= "11111111";
end case;
else
case rdsize is
when "0000" =>
length_o <= "00000";
select_o <= "00001000";
when "0001" =>
length_o <= "00000";
select_o <= "00000100";
when "0010" =>
length_o <= "00000";
select_o <= "00000010";
when "0011" =>
length_o <= "00000";
select_o <= "00000001";
when "0100" =>
length_o <= "00000";
select_o <= "00001100";
when "0101" =>
length_o <= "00000";
select_o <= "00000111";
when "0110" =>
length_o <= "00000";
select_o <= "00000011";
when "0111" =>
length_o <= "00000";
select_o <= "00011111";
when "1000" =>
length_o <= "00000";
select_o <= "00001111";
when "1001" =>
length_o <= "00000";
select_o <= "00111111";
when "1010" =>
length_o <= "00000";
select_o <= "01111111";
when "1011" =>
length_o <= "00001";
select_o <= "11111111";
when "1100" =>
length_o <= "00111";
select_o <= "11111111";
when "1101" =>
length_o <= "01111";
select_o <= "11111111";
when "1110" =>
length_o <= "10111";
select_o <= "11111111";
when others =>
length_o <= "11111";
select_o <= "11111111";
end case;
end if;
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 WriteClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_o : out std_logic;
responseNeeded_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadRead_i : in std_logic;
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture WriteClassInbound of WriteClassInbound is
type StateType is (RECEIVE_PACKET, READY);
signal state : StateType;
 
signal wdptr : std_logic;
signal wrsize : std_logic_vector(3 downto 0);
 
signal inboundAck : std_logic;
signal complete : std_logic;
 
signal packetIndex : natural range 0 to 69;
 
signal doubleWord : std_logic_vector(63 downto 16);
signal memoryWrite : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataIn : std_logic_vector(63 downto 0);
 
begin
 
inboundAck_o <= inboundAck;
 
ready_o <= complete when (state = READY) else '0';
 
WriteClass: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= RECEIVE_PACKET;
 
wdptr <= '0';
wrsize <= (others=>'0');
inboundAck <= '0';
complete <= '0';
responseNeeded_o <= '0';
packetIndex <= 0;
doubleWord <= (others=>'0');
 
memoryWrite <= '0';
memoryAddress <= (others=>'0');
memoryDataIn <= (others=>'0');
 
vc_o <= '0';
crf_o <= '0';
prio_o <= "00";
tt_o <= "00";
dstId_o <= (others=>'0');
srcId_o <= (others=>'0');
tid_o <= (others=>'0');
address_o <= (others=>'0');
elsif (clk'event and clk = '1') then
case state is
when RECEIVE_PACKET =>
if (inboundCyc_i = '1') then
if (inboundAck = '0') then
if (inboundStb_i = '1') then
if ((inboundAdr_i = x"55") or (inboundAdr_i = x"54")) then
-------------------------------------------------------------
-- NWRITE/NWRITER packet parser.
-------------------------------------------------------------
case (packetIndex) is
when 0 =>
-- x"0000" & ackid & vc & crf & prio & tt & ftype
vc_o <= inboundDat_i(9);
crf_o <= inboundDat_i(8);
prio_o <= inboundDat_i(7 downto 6);
tt_o <= inboundDat_i(5 downto 4);
packetIndex <= packetIndex + 1;
when 1 =>
-- destId
dstId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- srcId
srcId_o <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & wrsize & srcTID & address(28:13)
-- REMARK: Add support for extended addresses here...
if (inboundDat_i(31 downto 28) = "0101") then
responseNeeded_o <= '1';
else
responseNeeded_o <= '0';
end if;
wrsize <= inboundDat_i(27 downto 24);
tid_o <= inboundDat_i(23 downto 16);
address_o(28 downto 13) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 4 =>
-- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48)
address_o(12 downto 0) <= inboundDat_i(31 downto 19);
wdptr <= inboundDat_i(18);
address_o(30 downto 29) <= inboundDat_i(17 downto 16);
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-word(47:16)
doubleWord(47 downto 16) <= inboundDat_i;
packetIndex <= packetIndex + 1;
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 =>
-- double-word(15:0) & double-word(63:48)
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0);
packetIndex <= packetIndex + 1;
 
memoryWrite <= '1';
memoryDataIn <= doubleWord(63 downto 16) & inboundDat_i(31 downto 16);
when others =>
-- There should be no more content in an NWRITE/NWRITER request.
-- Discard.
end case;
inboundAck <= '1';
end if;
end if;
else
if (memoryWrite = '1') then
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
end if;
memoryWrite <= '0';
inboundAck <= '0';
end if;
else
if (packetIndex >= 6) then
complete <= '1';
state <= READY;
else
packetIndex <= 0;
memoryAddress <= (others=>'0');
end if;
end if;
 
when READY =>
---------------------------------------------------------------------
-- Wait for the handler of the packet to signal that it has been
-- processed.
---------------------------------------------------------------------
if (done_i = '1') then
packetIndex <= 0;
memoryAddress <= (others=>'0');
complete <= '0';
state <= RECEIVE_PACKET;
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
 
end case;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Transformation of wrsize and wdptr into length of access and byte lanes.
-----------------------------------------------------------------------------
process(clk, areset_n)
begin
if (areset_n = '0') then
length_o <= "00000";
select_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (complete = '1') then
if (wdptr = '0') then
case wrsize is
when "0000" =>
length_o <= "00000";
select_o <= "10000000";
when "0001" =>
length_o <= "00000";
select_o <= "01000000";
when "0010" =>
length_o <= "00000";
select_o <= "00100000";
when "0011" =>
length_o <= "00000";
select_o <= "00010000";
when "0100" =>
length_o <= "00000";
select_o <= "11000000";
when "0101" =>
length_o <= "00000";
select_o <= "11100000";
when "0110" =>
length_o <= "00000";
select_o <= "00110000";
when "0111" =>
length_o <= "00000";
select_o <= "11111000";
when "1000" =>
length_o <= "00000";
select_o <= "11110000";
when "1001" =>
length_o <= "00000";
select_o <= "11111100";
when "1010" =>
length_o <= "00000";
select_o <= "11111110";
when "1011" =>
length_o <= "00000";
select_o <= "11111111";
when others =>
length_o <= std_logic_vector(unsigned(memoryAddress)-1);
select_o <= "11111111";
end case;
else
case wrsize is
when "0000" =>
length_o <= "00000";
select_o <= "00001000";
when "0001" =>
length_o <= "00000";
select_o <= "00000100";
when "0010" =>
length_o <= "00000";
select_o <= "00000010";
when "0011" =>
length_o <= "00000";
select_o <= "00000001";
when "0100" =>
length_o <= "00000";
select_o <= "00001100";
when "0101" =>
length_o <= "00000";
select_o <= "00000111";
when "0110" =>
length_o <= "00000";
select_o <= "00000011";
when "0111" =>
length_o <= "00000";
select_o <= "00011111";
when "1000" =>
length_o <= "00000";
select_o <= "00001111";
when "1001" =>
length_o <= "00000";
select_o <= "00111111";
when "1010" =>
length_o <= "00000";
select_o <= "01111111";
when others =>
length_o <= std_logic_vector(unsigned(memoryAddress)-1);
select_o <= "11111111";
end case;
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Payload content memory.
-----------------------------------------------------------------------------
 
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>memoryWrite,
addressA_i=>memoryAddress,
dataA_i=>memoryDataIn,
clkB_i=>clk,
enableB_i=>payloadRead_i,
addressB_i=>payloadIndex_i,
dataB_o=>payload_o);
 
end architecture;
 
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rio_common.all;
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
entity ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
ready_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
tt_i : in std_logic_vector(1 downto 0);
dstid_i : in std_logic_vector(31 downto 0);
srcid_i : in std_logic_vector(31 downto 0);
tid_i : in std_logic_vector(7 downto 0);
error_i : in std_logic;
payloadPresent_i : in std_logic;
payloadLength_i : in std_logic_vector(4 downto 0);
payloadWrite_i : in std_logic;
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
architecture ResponseClassOutbound of ResponseClassOutbound is
signal header : std_logic_vector(31 downto 0);
type StateType is (WAIT_PACKET, SEND_RESPONSE,
WAIT_COMPLETE, RESPONSE_DONE);
signal state : StateType;
 
signal packetIndex : natural range 0 to 68;
 
signal responsePayloadIndex : std_logic_vector(4 downto 0);
signal responsePayload : std_logic_vector(15 downto 0);
signal memoryEnable : std_logic;
signal memoryAddress : std_logic_vector(4 downto 0);
signal memoryDataRead : std_logic_vector(63 downto 0);
 
begin
header <= x"0000" & "000000" & vc_i & crf_i & prio_i & tt_i & x"d";
 
Response: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= WAIT_PACKET;
 
packetIndex <= 0;
 
responsePayloadIndex <= (others=>'0');
responsePayload <= (others=>'0');
memoryEnable <= '0';
memoryAddress <= (others=>'0');
 
done_o <= '0';
outboundCyc_o <= '0';
outboundStb_o <= '0';
outboundDat_o <= (others=>'0');
elsif (clk'event and clk = '1') then
if (enable = '1') then
case state is
when WAIT_PACKET =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (ready_i = '1') then
outboundCyc_o <= '1';
outboundStb_o <= '1';
outboundDat_o <= header;
packetIndex <= 1;
responsePayloadIndex <= (others=>'0');
 
memoryEnable <= '1';
memoryAddress <= (others=>'0');
 
state <= SEND_RESPONSE;
end if;
 
when SEND_RESPONSE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (outboundAck_i = '1') then
case (packetIndex) is
when 1 =>
-- destination
outboundDat_o <= dstId_i;
packetIndex <= packetIndex + 1;
when 2 =>
-- source
outboundDat_o <= srcId_i;
packetIndex <= packetIndex + 1;
when 3 =>
-- transaction & status & targetTID & double-word0(63:48)
if (error_i = '0') then
if (payloadPresent_i = '0') then
outboundDat_o <= "0000" & "0000" & tid_i & x"0000";
state <= WAIT_COMPLETE;
else
outboundDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48);
end if;
else
outboundDat_o <= "0000" & "0111" & tid_i & x"0000";
state <= WAIT_COMPLETE;
end if;
packetIndex <= packetIndex + 1;
when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 =>
-- double-wordN(47:16)
outboundDat_o <= memoryDataRead(47 downto 16);
responsePayload <= memoryDataRead(15 downto 0);
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1);
packetIndex <= packetIndex + 1;
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 =>
-- double-wordN(15:0) & double-wordN(63:48)
outboundDat_o <= responsePayload & memoryDataRead(63 downto 48);
packetIndex <= packetIndex + 1;
 
responsePayloadIndex <=
std_logic_vector(unsigned(responsePayloadIndex) + 1);
if (responsePayloadIndex = payloadLength_i) then
state <= WAIT_COMPLETE;
else
packetIndex <= packetIndex + 1;
end if;
when others =>
-- Unallowed response length.
-- Dont do anything.
end case;
end if;
when WAIT_COMPLETE =>
-------------------------------------------------------------------
--
-------------------------------------------------------------------
if (outboundAck_i = '1') then
outboundCyc_o <= '0';
outboundStb_o <= '0';
state <= RESPONSE_DONE;
end if;
when RESPONSE_DONE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
memoryEnable <= '0';
if (ready_i = '0') then
state <= WAIT_PACKET;
done_o <= '0';
else
done_o <= '1';
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= WAIT_PACKET;
end case;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Payload content memory.
-----------------------------------------------------------------------------
PayloadMemory: MemorySimpleDualPort
generic map(ADDRESS_WIDTH=>5, DATA_WIDTH=>64)
port map(clkA_i=>clk,
enableA_i=>payloadWrite_i,
addressA_i=>payloadIndex_i,
dataA_i=>payload_i,
clkB_i=>clk,
enableB_i=>memoryEnable,
addressB_i=>memoryAddress,
dataB_o=>memoryDataRead);
 
end architecture;
/branches/2.0.0-development/rtl/vhdl/RioCommon.vhd
96,6 → 96,13
dataB_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;
 
-----------------------------------------------------------------------------
-- Logical layer component declarations.
-----------------------------------------------------------------------------
120,16 → 127,15
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
inboundCyc_o : out std_logic;
inboundStb_o : out std_logic;
inboundAdr_o : out std_logic_vector(7 downto 0);
inboundAdr_o : out std_logic_vector(3 downto 0);
inboundDat_o : out std_logic_vector(31 downto 0);
inboundAck_i : in std_logic;
inboundStall_i : in std_logic;
outboundCyc_i : in std_logic_vector(PORTS-1 downto 0);
outboundStb_i : in std_logic_vector(PORTS-1 downto 0);
outboundAdr_i : in std_logic_vector(PORTS-1 downto 0);
outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0);
outboundAck_o : out std_logic_vector(PORTS-1 downto 0));
outboundStall_o : out std_logic_vector(PORTS-1 downto 0));
end component;
 
component RioLogicalMaintenance is
165,6 → 171,12
end component;
component MaintenanceInbound is
generic(
ENABLE_READ_REQUEST : boolean := true;
ENABLE_WRITE_REQUEST : boolean := true;
ENABLE_READ_RESPONSE : boolean := true;
ENABLE_WRITE_RESPONSE : boolean := true;
ENABLE_PORT_WRITE : boolean := true);
port(
clk : in std_logic;
areset_n : in std_logic;
175,6 → 187,7
readResponseReady_o : out std_logic;
writeResponseReady_o : out std_logic;
portWriteReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
192,13 → 205,73
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundCyc_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(7 downto 0);
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundAck_o : out std_logic);
inboundStall_o : out std_logic);
end component;
component RequestClassInbound is
generic(
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
nreadReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
done_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundStall_o : out std_logic);
end component;
 
component WriteClassInbound is
generic(
ENABLE_NWRITE : boolean := true;
ENABLE_NWRITER : boolean := true;
EXTENDED_ADDRESS : natural range 0 to 2 := 0);
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
nwriteReady_o : out std_logic;
nwriterReady_o : out std_logic;
vc_o : out std_logic;
crf_o : out std_logic;
prio_o : out std_logic_vector(1 downto 0);
tt_o : out std_logic_vector(1 downto 0);
dstId_o : out std_logic_vector(31 downto 0);
srcId_o : out std_logic_vector(31 downto 0);
tid_o : out std_logic_vector(7 downto 0);
address_o : out std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0);
length_o : out std_logic_vector(4 downto 0);
select_o : out std_logic_vector(7 downto 0);
payloadIndex_i : in std_logic_vector(4 downto 0);
payload_o : out std_logic_vector(63 downto 0);
done_i : in std_logic;
inboundStb_i : in std_logic;
inboundAdr_i : in std_logic_vector(3 downto 0);
inboundDat_i : in std_logic_vector(31 downto 0);
inboundStall_o : out std_logic);
end component;
 
component MaintenanceOutbound is
port(
clk : in std_logic;
210,6 → 283,7
readResponseReady_i : in std_logic;
writeResponseReady_i : in std_logic;
portWriteReady_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
227,12 → 301,40
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundCyc_o : out std_logic;
outboundStb_o : out std_logic;
outboundAdr_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundAck_i : in std_logic);
outboundStall_i : in std_logic);
end component;
 
component ResponseClassOutbound is
port(
clk : in std_logic;
areset_n : in std_logic;
enable : in std_logic;
 
doneNoPayloadReady_i : in std_logic;
doneWithPayloadReady_i : in std_logic;
errorReady_i : in std_logic;
vc_i : in std_logic;
crf_i : in std_logic;
prio_i : in std_logic_vector(1 downto 0);
tt_i : in std_logic_vector(1 downto 0);
dstid_i : in std_logic_vector(31 downto 0);
srcid_i : in std_logic_vector(31 downto 0);
tid_i : in std_logic_vector(7 downto 0);
payloadLength_i : in std_logic_vector(4 downto 0);
payloadIndex_o : out std_logic_vector(4 downto 0);
payload_i : in std_logic_vector(63 downto 0);
done_o : out std_logic;
outboundStb_o : out std_logic;
outboundAdr_o : out std_logic;
outboundDat_o : out std_logic_vector(31 downto 0);
outboundStall_i : in std_logic);
end component;
 
component RioPacketBuffer is
generic(
SIZE_ADDRESS_WIDTH : natural := 6;
334,8 → 436,12
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_MAINTENANCE_PORT_WRITE : std_logic_vector(3 downto 0) := "0100";
constant TTYPE_NREAD_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
constant TTYPE_NWRITE_TRANSACTION : std_logic_vector(3 downto 0) := "0100";
constant TTYPE_NWRITER_TRANSACTION : std_logic_vector(3 downto 0) := "0101";
constant TTYPE_RESPONSE_NO_PAYLOAD : std_logic_vector(3 downto 0) := "0000";
constant TTYPE_RESPONSE_WITH_PAYLOAD : std_logic_vector(3 downto 0) := "1000";
 
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";
494,12 → 600,6
function byteToString(constant byte : std_logic_vector(7 downto 0))
return string;
 
-----------------------------------------------------------------------------
-- Function to print a std_logic_vector.
-----------------------------------------------------------------------------
function to_string(constant value : std_logic_vector)
return string;
---------------------------------------------------------------------------
-- Procedure to print to report file and output
---------------------------------------------------------------------------
520,47 → 620,6
---------------------------------------------------------------------------
procedure PrintE( constant str : string );
 
---------------------------------------------------------------------------
-- Procedures for test control.
---------------------------------------------------------------------------
 
procedure TestWarning(constant tag : in string);
procedure TestError(constant tag : in string;
constant stopAtError : in boolean := true);
procedure TestCompare(constant expression : in boolean;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in std_logic;
constant expected : in std_logic;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in std_logic_vector;
constant expected : in std_logic_vector;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in natural;
constant expected : in natural;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestCompare(constant got : in time;
constant expected : in time;
constant tag : in string := "";
constant stopAtError : in boolean := true);
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true);
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
signal ackSignal : inout std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true);
 
procedure TestEnd;
 
end package;
 
-------------------------------------------------------------------------------
990,48 → 1049,6
return returnValue;
end function;
-----------------------------------------------------------------------------
-- Function to print std_logic_vector.
-----------------------------------------------------------------------------
function to_string(constant value : std_logic) return string is
variable s : string(1 to 1);
begin
if (value = '0') then
s(1) := '0';
elsif (value = '1') then
s(1) := '1';
elsif (value = 'U') then
s(1) := 'U';
elsif (value = 'X') then
s(1) := 'X';
else
s(1) := '?';
end if;
return s;
end function;
function to_string(constant value : std_logic_vector) return string is
variable s : string(1 to value'length);
variable index : positive;
variable i : natural;
begin
index := 1;
for i in value'range loop
if (value(i) = '0') then
s(index) := '0';
elsif (value(i) = '1') then
s(index) := '1';
elsif (value(i) = 'U') then
s(index) := 'U';
elsif (value(i) = 'X') then
s(index) := 'X';
else
s(index) := '?';
end if;
index := index + 1;
end loop;
return s;
end function;
---------------------------------------------------------------------------
-- Procedure to print test report
---------------------------------------------------------------------------
1088,217 → 1105,6
report str severity error;
end PrintE;
 
---------------------------------------------------------------------------
-- Procedures to handle tests.
---------------------------------------------------------------------------
 
procedure TestWarning(constant tag : in string) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":WARNING:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
end procedure;
procedure TestError(constant tag : in string;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant expression : in boolean;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (not expression) then
write(writeBuffer, string'(":FAILED:"));
else
write(writeBuffer, string'(":PASSED:"));
end if;
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) and (not expression) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in std_logic;
constant expected : in std_logic;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & to_string(got));
write(writeBuffer, ":expected=" & to_string(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in std_logic_vector;
constant expected : in std_logic_vector;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & to_string(got));
write(writeBuffer, ":expected=" & to_string(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in natural;
constant expected : in natural;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, ":got=" & integer'image(got));
write(writeBuffer, ":expected=" & integer'image(expected));
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
procedure TestCompare(constant got : in time;
constant expected : in time;
constant tag : in string := "";
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
write(writeBuffer, now);
if (expected /= got) then
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
write(writeBuffer, string'(":got="));
write(writeBuffer, got);
write(writeBuffer, string'(":expected="));
write(writeBuffer, expected);
else
write(writeBuffer, string'(":PASSED:"));
write(writeBuffer, tag);
end if;
writeline(OUTPUT, writeBuffer);
 
if (stopAtError) and (expected /= got) then
std.env.stop(0);
end if;
end procedure;
 
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
if (waitSignal /= waitValue) then
wait until waitSignal = waitValue for waitTime;
if (waitSignal /= waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end if;
end procedure;
procedure TestWait(signal waitSignal : in std_logic;
constant waitValue : in std_logic;
signal ackSignal : inout std_logic;
constant tag : in string := "";
constant waitTime : in time := 1 ms;
constant stopAtError : in boolean := true) is
variable writeBuffer : line;
begin
if (waitSignal /= waitValue) then
 
wait until waitSignal = waitValue for waitTime;
if (waitSignal /= waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end if;
ackSignal <= not ackSignal;
wait until waitSignal /= waitValue for waitTime;
if (waitSignal = waitValue) then
write(writeBuffer, now);
write(writeBuffer, string'(":FAILED:"));
write(writeBuffer, tag);
writeline(OUTPUT, writeBuffer);
if (stopAtError) then
std.env.stop(0);
end if;
end if;
end procedure;
 
procedure TestEnd is
variable writeBuffer : line;
begin
write(writeBuffer, now);
write(writeBuffer, string'(":COMPLETED"));
writeline(OUTPUT, writeBuffer);
std.env.stop(0);
end TestEnd;
 
end rio_common;
 
 
/branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd
6,10 → 6,12
-- http://www.opencores.org/cores/rio/
--
-- Description
-- Contains a platform to build endpoints on.
-- Contains a converter of RapidIO maintenance packets into a Wishbone similar
-- access. It relies on the Maintenance-packet modules from
-- RioLogicalPackets.vhd to function.
--
-- To Do:
-- - Clean up the code for reading. Works but messy.
-- - Clean up the code for reading. Works but it is messy.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
146,6 → 148,7
---------------------------------------------------------------------
--
---------------------------------------------------------------------
payloadIndex <= (others=>'0');
done_o <= '0';
if (readRequestReady_i = '1') then
state <= CONFIG_READ_START;
329,7 → 332,7
status_o <= "0111";
state <= CONFIG_WRITE_RESPONSE;
end if;
payloadIndex <= "0001";
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1);
when CONFIG_WRITE =>
---------------------------------------------------------------------
/branches/2.0.0-development/rtl/vhdl/RioSwitch.vhd
21,7 → 21,8
-- sending port can see if a receiving port is up or not.
-- - Add support for extended route.
-- - Add validity-bit to know if a route has been activly set for a particular
-- deviceId.
-- deviceId. Currently, we rely on that the routing table memory is
-- initialized in the enumeration or at device startup.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
52,16 → 53,11
-- from http://www.opencores.org/lgpl.shtml
--
-------------------------------------------------------------------------------
-- Revision history.
-- - Adding support for all sizes of maintenance packets.
-- - Adding configAck to external config-space interface.
-------------------------------------------------------------------------------
 
 
-------------------------------------------------------------------------------
-- RioSwitch
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
512,7 → 508,6
readFrame_o <= '0';
readFrameRestart_o <= '0';
 
-- REMARK: Add support for aborted frames...
case masterState is
 
when STATE_IDLE =>
676,8 → 671,8
---------------------------------------------------------------------
 
-- Wait for the target port to complete the request.
-- REMARK: Remove the ack-condition, we know that the write takes one
-- cycle...
-- REMARK: Remove the ack-condition to increase performance, we know
-- that the write takes one cycle.
if (masterAck_i = '1') then
-- The target port is ready.
 
998,15 → 993,14
-- Signals between RioLogicalCommon and PacketHandler.
-----------------------------------------------------------------------------
 
signal inboundCyc : std_logic;
signal inboundStb : std_logic;
signal inboundAdr : std_logic_vector(7 downto 0);
signal inboundAdr : std_logic_vector(3 downto 0);
signal inboundDat : std_logic_vector(31 downto 0);
signal inboundAck : std_logic;
signal outboundCyc : std_logic_vector(0 downto 0);
signal inboundStall : std_logic;
signal outboundStb : std_logic_vector(0 downto 0);
signal outboundAdr : std_logic_vector(0 downto 0);
signal outboundDat : std_logic_vector(31 downto 0);
signal outboundAck : std_logic_vector(0 downto 0);
signal outboundStall : std_logic_vector(0 downto 0);
 
-----------------------------------------------------------------------------
-- Signals between PacketHandlers and maintenance controllers.
1095,7 → 1089,6
signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0);
signal configAck, configAckInternal : std_logic;
 
-- REMARK: Make these variables instead...
signal discovered : std_logic;
signal hostBaseDeviceIdLocked : std_logic;
signal hostBaseDeviceId : std_logic_vector(15 downto 0);
1109,8 → 1102,7
-----------------------------------------------------------------------------
-- Normal switch port instance interfacing the switch interconnect.
-----------------------------------------------------------------------------
-- REMARK: PORT_INDEX is not used in this instantiation.
-- REMARK: Add generic to disable the maintenance routing to this port...
-- Note that PORT_INDEX is not used in this instantiation and set to zero.
PortInst: SwitchPort
generic map(
MAINTENANCE_LOOKUP=>true,
1166,8 → 1158,9
-- Packet queue.
-- This queue should only contain one packet.
-----------------------------------------------------------------------------
-- REMARK: Use a packet-buffer with a configurable maximum sized packet...
-- the size of the memory is too large...
-- REMARK: Use a packet-buffer with a configurable maximum sized packet. The
-- size of the resulting memory is larger than needed since maintenance
-- packets never contain more than 8 double-words.
PacketQueue: RioPacketBuffer
generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7)
port map(
1218,22 → 1211,19
writeFrameAbort_o=>outboundWriteFrameAbort,
writeContent_o=>outboundWriteContent,
writeContentData_o=>outboundWriteContentData,
inboundCyc_o=>inboundCyc,
inboundStb_o=>inboundStb,
inboundAdr_o=>inboundAdr,
inboundDat_o=>inboundDat,
inboundAck_i=>inboundAck,
outboundCyc_i=>outboundCyc,
outboundStb_i=>outboundStb,
inboundStall_i=>inboundStall,
outboundStb_i=>outboundStb,
outboundAdr_i=>outboundAdr,
outboundDat_i=>outboundDat,
outboundAck_o=>outboundAck);
outboundStall_o=>outboundStall);
 
-----------------------------------------------------------------------------
-- Inbound maintenance packet parser.
-- Unpack inbound maintenance packets.
-----------------------------------------------------------------------------
-- REMARK: add another receiver that discards all other packet types...
-- REMARK: Connect enable to something...
payloadIndexInbound <= payloadIndexOutbound when (forwardPacket = '1') else payloadIndexMaint;
doneInbound <= doneOutbound when (forwardPacket = '1') else doneMaint;
InboundPacket: MaintenanceInbound
1260,11 → 1250,10
payloadIndex_i=>payloadIndexInbound,
payload_o=>payloadInbound,
done_i=>doneInbound,
inboundCyc_i=>inboundCyc,
inboundStb_i=>inboundStb,
inboundAdr_i=>inboundAdr,
inboundDat_i=>inboundDat,
inboundAck_o=>inboundAck);
inboundStall_o=>inboundStall);
 
-----------------------------------------------------------------------------
-- Outbound maintenance packet generator.
1280,7 → 1269,6
hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff";
payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint;
payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint;
-- REMARK: Connect enable to something...
OutboundPacket: MaintenanceOutbound
port map(
clk=>clk, areset_n=>areset_n, enable=>'1',
1305,10 → 1293,10
payloadIndex_o=>payloadIndexOutbound,
payload_i=>payloadOutbound,
done_o=>doneOutbound,
outboundCyc_o=>outboundCyc(0),
outboundStb_o=>outboundStb(0),
outboundStb_o=>outboundStb(0),
outboundAdr_o=>outboundAdr(0),
outboundDat_o=>outboundDat,
outboundAck_i=>outboundAck(0));
outboundStall_i=>outboundStall(0));
 
-----------------------------------------------------------------------------
-- Main switch maintenance controller.
1319,7 → 1307,7
RioSwitchMaintenance: process(clk, areset_n)
type MasterStateType is (STATE_IDLE,
STATE_START_PORT_LOOKUP,
STATE_READ_PORT_LOOKUP,
STATE_WAIT_PORT_LOOKUP,
STATE_WAIT_COMPLETE);
variable masterState : MasterStateType;
begin
1337,9 → 1325,8
 
when STATE_IDLE =>
---------------------------------------------------------------------
--
-- Wait for frame to be available.
---------------------------------------------------------------------
-- Wait for frame to be available.
-- REMARK: Discard erronous frames.
sendPacket <= '0';
if (((readRequestInbound = '1') or (writeRequestInbound = '1')) and (hopInbound = x"00")) then
1346,8 → 1333,10
masterState := STATE_WAIT_COMPLETE;
forwardPacket <= '0';
outboundFramePort <= inboundFramePort;
elsif (((readResponseInbound = '1') or ((readRequestInbound = '1') and (hopInbound /= x"00"))) or
((writeResponseInbound = '1') or ((writeRequestInbound = '1') and (hopInbound /= x"00"))) or
elsif ((readResponseInbound = '1') or
((readRequestInbound = '1') and (hopInbound /= x"00")) or
(writeResponseInbound = '1') or
((writeRequestInbound = '1') and (hopInbound /= x"00")) or
(portWriteInbound = '1')) then
masterState := STATE_START_PORT_LOOKUP;
forwardPacket <= '1';
1355,20 → 1344,20
when STATE_START_PORT_LOOKUP =>
---------------------------------------------------------------------
--
-- The destination port of the packet should be read from the routing
-- table.
---------------------------------------------------------------------
 
-- Initiate a port-lookup of the destination address.
lookupStb_o <= '1';
lookupAddr_o <= dstIdInbound(15 downto 0);
masterState := STATE_READ_PORT_LOOKUP;
masterState := STATE_WAIT_PORT_LOOKUP;
 
when STATE_READ_PORT_LOOKUP =>
when STATE_WAIT_PORT_LOOKUP =>
---------------------------------------------------------------------
--
-- Wait for the destination port lookup to complete.
---------------------------------------------------------------------
-- Wait for the routing table to complete the request.
if (lookupAck_i = '1') then
-- The address lookup is complete.
1385,10 → 1374,9
 
when STATE_WAIT_COMPLETE =>
---------------------------------------------------------------------
--
-- Indicate that the packet can be sent and wait for it to be
-- transmitted.
---------------------------------------------------------------------
-- REMARK: Wait for the packet to be fully transmitted to the target
-- port. Then reset everything for the reception of a new packet.
sendPacket <= '1';
if (doneInbound = '1') then
masterState := STATE_IDLE;
1406,7 → 1394,6
-- Bridge between the inbound RapidIO maintenance packets to the internal
-- config-space bus.
-----------------------------------------------------------------------------
-- REMARK: Connect enable...
readRequestMaint <= (readRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
writeRequestMaint <= (writeRequestInbound and sendPacket) when (forwardPacket = '0') else '0';
MaintenanceBridge: RioLogicalMaintenance
/branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd
6,15 → 6,15
-- http://www.opencores.org/cores/rio/
--
-- Description
-- Contains a platform to build endpoints on.
-- Contains a platform to build endpoints on. It handles CRC insertion/removal
-- and unpacks the deviceId in a packet into a fixed 32-bit to make the parsing
-- of packets in higher layers easier. It also discards packets that does not
-- have a handler.
--
-- To Do:
-- - Fix bug with one extra write in inbound direction.
-- - Rewrite to decrease resource usage.
-- - Clean up and increase the speed of the interface to packet handlers.
-- - 8-bit deviceId has not been verified, fix.
-- - 8-bit deviceId has not been implemented, fix either as seperate
-- architecture or an architecture with combined 8- and 16-bit support.
-- - Egress; Place packets in different queues depending on the packet priority?
-- - Add verification of all sizes of packets.
--
-- Author(s):
-- - Magnus Rosenius, magro732@opencores.org
51,16 → 51,32
-- RioLogicalCommon.
-------------------------------------------------------------------------------
-- Ingress:
-- * Removes in-the-middle and trailing CRC.
-- * Forwards packets to logical-layer handlers depending on ftype and
-- transaction (output as address).
-- * Outputs header and deviceIDs in seperate accesses to facilitate 8- and
-- 16-bit deviceAddress support. All fields are right-justified.
-- * Removes in-the-middle CRC. The trailing CRC is not removed since it is not
-- possible to know in which half-word it is placed without knowing how the
-- packet should be parsed.
-- * Forwards packets to logical-layer handlers depending on ftype. The
-- ftype-field is output as address.
-- * Outputs header and deviceIDs in seperate accesses to facilitate supporting
-- different deviceId sizes. All fields are right-justified.
-- * stall_i is used to stop the flow of data. The flow will continue when
-- stall_i is deasserted. The stall_i signals should not be registered. If
-- there is no handler for a packet, stall_i will not go high and the packet
-- will be automatically discarded.
-- Egress:
-- * Adds in-the-middle and trailing CRC.
-- * Receives packets from logical-layer handlers.
-- * Receives header and deviceIDs in seperate accesses to facilitate 8- and
-- 16-bit deviceAddress support. All fields are right-justified.
-- * Receives packets from a configurable number of logical-layer handlers.
-- This enables more complex endpoints with several independent
-- funtionalities.
-- * Receives header and deviceId in seperate accesses to facilitate
-- supporting different deviceId sizes. All fields are right-justified. The
-- size of the deviceId is indicated by the TT-field in the header.
-- * The adr_i-input signal on the egress side is used to indicate if the last
-- word contains one or two half-words. This is used to know where to insert
-- the trailing CRC. It should be set at the start of the frame. If all
-- frames always have the CRC in the same place it is ok to set this signal
-- constant.
-- Examples of how to write a handler for a packet can be found in
-- RioLogicalPackets.vhd.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
73,7 → 89,7
-------------------------------------------------------------------------------
entity RioLogicalCommon is
generic(
PORTS : natural);
PORTS : natural := 1);
port(
clk : in std_logic;
areset_n : in std_logic;
91,16 → 107,15
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
inboundCyc_o : out std_logic;
inboundStb_o : out std_logic;
inboundAdr_o : out std_logic_vector(7 downto 0);
inboundAdr_o : out std_logic_vector(3 downto 0);
inboundDat_o : out std_logic_vector(31 downto 0);
inboundAck_i : in std_logic;
inboundStall_i : in std_logic;
outboundCyc_i : in std_logic_vector(PORTS-1 downto 0);
outboundStb_i : in std_logic_vector(PORTS-1 downto 0);
outboundAdr_i : in std_logic_vector(PORTS-1 downto 0);
outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0);
outboundAck_o : out std_logic_vector(PORTS-1 downto 0));
outboundStall_o : out std_logic_vector(PORTS-1 downto 0));
end entity;
 
 
117,12 → 132,14
areset_n : in std_logic;
 
stb_i : in std_logic_vector(WIDTH-1 downto 0);
dataM_i : in std_logic_vector(32*WIDTH-1 downto 0);
ack_o : out std_logic_vector(WIDTH-1 downto 0);
adr_i : in std_logic_vector(WIDTH-1 downto 0);
data_i : in std_logic_vector(32*WIDTH-1 downto 0);
stall_o : out std_logic_vector(WIDTH-1 downto 0);
 
stb_o : out std_logic;
dataS_o : out std_logic_vector(31 downto 0);
ack_i : in std_logic);
adr_o : out std_logic;
data_o : out std_logic_vector(31 downto 0);
stall_i : in std_logic);
end component;
component RioLogicalCommonIngress is
136,11 → 153,10
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
 
inboundCyc_o : out std_logic;
inboundStb_o : out std_logic;
inboundAdr_o : out std_logic_vector(7 downto 0);
inboundDat_o : out std_logic_vector(31 downto 0);
inboundAck_i : in std_logic);
stb_o : out std_logic;
adr_o : out std_logic_vector(3 downto 0);
dat_o : out std_logic_vector(31 downto 0);
stall_i : in std_logic);
end component;
 
component RioLogicalCommonEgress is
154,15 → 170,16
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
outboundCyc_i : in std_logic;
outboundStb_i : in std_logic;
outboundDat_i : in std_logic_vector(31 downto 0);
outboundAck_o : out std_logic);
stb_i : in std_logic;
adr_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
stall_o : out std_logic);
end component;
 
signal outboundStb : std_logic;
signal outboundAdr : std_logic;
signal outboundDat : std_logic_vector(31 downto 0);
signal outboundAck : std_logic;
signal outboundStall : std_logic;
begin
 
174,22 → 191,23
readContent_o=>readContent_o,
readContentEnd_i=>readContentEnd_i,
readContentData_i=>readContentData_i,
inboundCyc_o=>inboundCyc_o,
inboundStb_o=>inboundStb_o,
inboundAdr_o=>inboundAdr_o,
inboundDat_o=>inboundDat_o,
inboundAck_i=>inboundAck_i);
stb_o=>inboundStb_o,
adr_o=>inboundAdr_o,
dat_o=>inboundDat_o,
stall_i=>inboundStall_i);
 
EgressInterconnect: RioLogicalCommonInterconnect
generic map(WIDTH=>PORTS)
port map(
clk=>clk, areset_n=>areset_n,
stb_i=>outboundStb_i,
dataM_i=>outboundDat_i,
ack_o=>outboundAck_o,
stb_o=>outboundStb,
dataS_o=>outboundDat,
ack_i=>outboundAck);
stb_i=>outboundStb_i,
adr_i=>outboundAdr_i,
data_i=>outboundDat_i,
stall_o=>outboundStall_o,
stb_o=>outboundStb,
adr_o=>outboundAdr,
data_o=>outboundDat,
stall_i=>outboundStall);
 
Egress: RioLogicalCommonEgress
port map(
199,10 → 217,10
writeFrameAbort_o=>writeFrameAbort_o,
writeContent_o=>writeContent_o,
writeContentData_o=>writeContentData_o,
outboundCyc_i=>'1',
outboundStb_i=>outboundStb,
outboundDat_i=>outboundDat,
outboundAck_o=>outboundAck);
stb_i=>outboundStb,
adr_i=>outboundAdr,
dat_i=>outboundDat,
stall_o=>outboundStall);
 
end architecture;
 
231,239 → 249,114
readContentEnd_i : in std_logic;
readContentData_i : in std_logic_vector(31 downto 0);
 
inboundCyc_o : out std_logic;
inboundStb_o : out std_logic;
inboundAdr_o : out std_logic_vector(7 downto 0);
inboundDat_o : out std_logic_vector(31 downto 0);
inboundAck_i : in std_logic);
stb_o : out std_logic;
adr_o : out std_logic_vector(3 downto 0);
dat_o : out std_logic_vector(31 downto 0);
stall_i : in std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioLogicalCommonIngress.
-- Architecture for RioLogicalCommonIngress16.
-- Only 16-bit deviceId are supported.
-------------------------------------------------------------------------------
architecture RioLogicalCommonIngress of RioLogicalCommonIngress is
type StateType is (IDLE,
WAIT_HEADER_0, HEADER_0, HEADER_1,
SEND_HEADER, SEND_DESTINATION, SEND_SOURCE,
FORWARD_SHORT, FORWARD_CRC, FORWARD_LONG, FORWARD_LAST,
END_PACKET);
signal state : StateType;
architecture RioLogicalCommonIngress16 of RioLogicalCommonIngress is
 
signal packetPosition : natural range 0 to 68;
signal packetPosition : natural range 0 to 74;
 
signal loadValue, loadValue16 : std_logic_vector(63 downto 0);
signal packetContent : std_logic_vector(63 downto 0);
 
signal tt : std_logic_vector(1 downto 0);
signal ftype : std_logic_vector(3 downto 0);
signal transaction : std_logic_vector(3 downto 0);
 
signal readContent : std_logic;
signal readFrame : std_logic;
begin
readContent_o <= readContent;
readFrame_o <= readFrame;
adr_o <= ftype;
dat_o <= packetContent(63 downto 32);
 
process(clk, areset_n)
loadValue16 <=
(x"0000" & packetContent(31 downto 16) & readContentData_i) when (packetPosition = 4) else
(x"0000" & packetContent(31 downto 0) & x"0000") when (packetPosition = 5) else
(packetContent(31 downto 16) & readContentData_i & x"0000") when (packetPosition < 24) else
(packetContent(31 downto 16) & readContentData_i(15 downto 0) & x"00000000") when (packetPosition = 24) else
(readContentData_i & x"00000000");
loadValue <= loadValue16 when (tt = "01") else (x"0000" & readContentData_i & x"0000");
shifter: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= IDLE;
packetContent <= (others=>'0');
elsif (clk'event and clk = '1') then
if ((stall_i = '0') and (readFrameEmpty_i = '0')) then
packetContent <= loadValue;
end if;
end if;
end process;
 
packetCounter: process(clk, areset_n)
begin
if (areset_n = '0') then
packetPosition <= 0;
packetContent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (readFrame = '1') or (readFrameEmpty_i = '1') then
packetPosition <= 0;
elsif (stall_i = '0') then
packetPosition <= packetPosition + 1;
end if;
end if;
end process;
 
headerRegister: process(clk, areset_n)
begin
if (areset_n = '0') then
tt <= "00";
ftype <= "0000";
transaction <= "0000";
elsif (clk'event and clk = '1') then
if (readFrame = '1') then
tt <= "00";
ftype <= "0000";
elsif (stall_i = '0') and (packetPosition = 3) then
tt <= readContentData_i(21 downto 20);
ftype <= readContentData_i(19 downto 16);
end if;
end if;
end process;
 
readContent_o <= '0';
readFrame_o <= '0';
 
inboundCyc_o <= '0';
inboundStb_o <= '0';
inboundAdr_o <= (others=>'0');
inboundDat_o <= (others=>'0');
controller: process(clk, areset_n)
begin
if (areset_n = '0') then
readContent <= '0';
readFrame <= '0';
stb_o <= '0';
elsif (clk'event and clk = '1') then
readContent_o <= '0';
readFrame_o <= '0';
case state is
when IDLE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
packetPosition <= 0;
if (readFrameEmpty_i = '0') then
readContent_o <= '1';
state <= WAIT_HEADER_0;
end if;
when WAIT_HEADER_0 =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
readContent_o <= '1';
state <= HEADER_0;
 
when HEADER_0 =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
packetContent <= packetContent(31 downto 0) & readContentData_i;
packetPosition <= packetPosition + 1;
readContent_o <= '1';
 
tt <= readContentData_i(21 downto 20);
ftype <= readContentData_i(19 downto 16);
 
state <= HEADER_1;
when HEADER_1 =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
packetContent <= packetContent(31 downto 0) & readContentData_i;
packetPosition <= packetPosition + 1;
 
if (tt = "00") then
transaction <= readContentData_i(31 downto 28);
elsif (tt = "01") then
transaction <= readContentData_i(15 downto 12);
end if;
state <= SEND_HEADER;
 
when SEND_HEADER =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
inboundCyc_o <= '1';
inboundStb_o <= '1';
inboundAdr_o <= ftype & transaction;
inboundDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(47 downto 0) & x"0000";
 
state <= SEND_DESTINATION;
 
when SEND_DESTINATION =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
if (tt = "00") then
inboundDat_o <= x"000000" & packetContent(63 downto 56);
packetContent <= packetContent(55 downto 0) & x"00";
elsif (tt = "01") then
inboundDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(47 downto 0) & x"0000";
end if;
 
state <= SEND_SOURCE;
end if;
when SEND_SOURCE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
if (tt = "00") then
inboundDat_o <= x"000000" & packetContent(63 downto 56);
packetContent <= packetContent(55 downto 0) & x"00";
elsif (tt = "01") then
inboundDat_o <= x"0000" & packetContent(63 downto 48);
packetContent <= packetContent(47 downto 32) & readContentData_i & x"0000";
readContent_o <= '1';
end if;
 
state <= FORWARD_SHORT;
end if;
when FORWARD_SHORT =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
packetPosition <= packetPosition + 1;
 
if (tt = "00") then
inboundDat_o <= packetContent(63 downto 32);
packetContent <= packetContent(31 downto 0) & readContentData_i;
elsif (tt = "01") then
inboundDat_o <= packetContent(63 downto 32);
packetContent <= packetContent(31 downto 16) & readContentData_i & x"0000";
end if;
if (readContentEnd_i = '0') then
if (packetPosition = 18) then
state <= FORWARD_CRC;
end if;
readContent_o <= '1';
if (stall_i = '0') then
case packetPosition is
when 0 =>
readContent <= '0';
readFrame <= '0';
stb_o <= '0';
when 1 =>
readContent <= '1';
when 2 =>
readContent <= '1';
when 3 =>
readContent <= '0';
stb_o <= '1';
when others =>
if (readFrame = '0') then
stb_o <= not readContentEnd_i;
readFrame <= readContentEnd_i;
readContent <= not readContentEnd_i;
else
readFrame_o <= '1';
state <= FORWARD_LAST;
readFrame <= '0';
end if;
end if;
 
when FORWARD_CRC =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
inboundDat_o <= packetContent(63 downto 32);
 
packetPosition <= packetPosition + 1;
packetContent <=
packetContent(31 downto 16) & readContentData_i(15 downto 0) & x"00000000";
if (readContentEnd_i = '0') then
readContent_o <= '1';
state <= FORWARD_LONG;
else
readFrame_o <= '1';
state <= FORWARD_LAST;
end if;
end if;
 
when FORWARD_LONG =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
inboundDat_o <= packetContent(63 downto 32);
 
packetPosition <= packetPosition + 1;
packetContent <=
readContentData_i & x"00000000";
if (readContentEnd_i = '0') then
readContent_o <= '1';
else
readFrame_o <= '1';
state <= FORWARD_LAST;
end if;
end if;
 
when FORWARD_LAST =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
inboundDat_o <= packetContent(63 downto 32);
state <= END_PACKET;
end if;
when END_PACKET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (inboundAck_i = '1') then
inboundCyc_o <= '0';
inboundStb_o <= '0';
state <= IDLE;
end if;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= IDLE;
end case;
end case;
end if;
end if;
end process;
 
473,11 → 366,6
 
-------------------------------------------------------------------------------
-- RioLogicalCommonEgress.
-- Only 8-bit and 16-bit deviceId are supported. The first write must contain
-- the 16-bit header, the second write must contain the destination address and
-- the third must contain the source address.
-- CRC is calculated during the transfer and is inserted at byte 81 and 82 and
-- appended to the packet when it ends.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
499,308 → 387,268
writeContent_o : out std_logic;
writeContentData_o : out std_logic_vector(31 downto 0);
 
outboundCyc_i : in std_logic;
outboundStb_i : in std_logic;
outboundDat_i : in std_logic_vector(31 downto 0);
outboundAck_o : out std_logic);
stb_i : in std_logic;
adr_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
stall_o : out std_logic);
end entity;
 
 
-------------------------------------------------------------------------------
-- Architecture for RioLogicalCommonEgress.
-- Architecture for RioLogicalCommonEgress16.
-- Only 16-bit deviceId are supported. The first write must contain
-- the 16-bit header, the second write must contain the destination address and
-- the third must contain the source address.
-- CRC is calculated during the transfer and is inserted at byte 81 and 82 and
-- appended to the packet when it ends.
-------------------------------------------------------------------------------
architecture RioLogicalCommonEgress of RioLogicalCommonEgress is
architecture RioLogicalCommonEgress16 of RioLogicalCommonEgress 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;
 
type StateType is (IDLE,
HEADER_GET, HEADER_ACK,
DESTINATION_GET, DESTINATION_ACK,
SOURCE_GET, SOURCE_ACK,
CONTENT_GET, CONTENT_ACK,
CRC_APPEND, CRC_UPDATE, CRC_LAST, SEND_FRAME,
RESTART_FRAME, WAIT_UPDATE);
signal state : StateType;
signal packetPosition : natural range 0 to 69;
signal stb, cycleEndCurrent, cycleEndNext : std_logic;
signal temp : std_logic_vector(15 downto 0);
signal tt : std_logic_vector(1 downto 0);
signal dstAddr : std_logic_vector(7 downto 0);
signal packetPosition : natural range 0 to 72;
 
signal loadValue : std_logic_vector(47 downto 0);
signal packetContent : std_logic_vector(47 downto 0);
signal packetContentReady : std_logic;
signal packetContentOdd : std_logic;
signal packetContentLong : std_logic;
signal packetContentEnd : std_logic;
signal packetContentPending : std_logic;
 
signal writeContent : std_logic;
signal writeContentData1 : std_logic_vector(31 downto 0);
signal writeContentData2 : std_logic_vector(31 downto 0);
signal writeFrame : std_logic;
signal writeContentData : std_logic_vector(31 downto 0);
 
signal crcReset : std_logic;
signal crc16Current, crc16Temp, crc16Next: std_logic_vector(15 downto 0);
 
signal crcCurrent, crcTemp, crcNext: std_logic_vector(15 downto 0);
begin
 
writeContent_o <= writeContent;
writeContentData_o <= writeContentData1;
 
process(clk, areset_n)
-----------------------------------------------------------------------------
-- Packet cycle end detection.
-----------------------------------------------------------------------------
stbDelayFF: process(clk, areset_n)
begin
if (areset_n = '0') then
crc16Current <= x"0000";
stb <= '0';
elsif (clk'event and clk = '1') then
if (crcReset = '1') then
crc16Current <= x"ffff";
elsif (writeContent = '1') then
crc16Current <= crc16Next;
if (writeFrame = '1') then
stb <= '0';
elsif (writeFrameFull_i = '0') then
stb <= stb_i;
end if;
end if;
end process;
process(clk, areset_n)
cycleEndNext <= (stb and (not stb_i));
cycleEndFF: process(clk, areset_n)
begin
if (areset_n = '0') then
state <= IDLE;
cycleEndCurrent <= '0';
elsif (clk'event and clk = '1') then
if (writeFrame = '1') then
cycleEndCurrent <= '0';
elsif (cycleEndNext = '1') then
cycleEndCurrent <= '1';
end if;
end if;
end process;
packetContentEnd <= cycleEndNext or cycleEndCurrent;
 
-----------------------------------------------------------------------------
-- Packet positioning.
-----------------------------------------------------------------------------
packetPositionCounter: process(clk, areset_n)
begin
if (areset_n = '0') then
packetPosition <= 0;
elsif (clk'event and clk = '1') then
if (writeFrame = '1') then
packetPosition <= 0;
elsif (stb_i = '1') and (writeFrameFull_i = '0') then
packetPosition <= packetPosition + 1;
end if;
end if;
end process;
 
tt <= (others=>'0');
dstAddr <= (others=>'0');
-----------------------------------------------------------------------------
-- Packet content creation.
-----------------------------------------------------------------------------
-- REMARK: The critical path is the crcNext through the loadValue-mux into
-- packetContent. Register this path if possible.
loadValue <=
(packetContent(31 downto 0) & dat_i(15 downto 0)) when (packetContentReady = '0') else
(packetContent(15 downto 0) & dat_i) when (packetContentLong = '0') else
(crcNext & packetContent(15 downto 0) & x"0000") when (packetContentPending = '1') else
(dat_i & x"0000");
packetContentPlace: process(clk, areset_n)
begin
if (areset_n = '0') then
packetContent <= (others=>'0');
elsif (clk'event and clk = '1') then
if (stb_i = '1') or (stb = '1') then
packetContent <= loadValue;
end if;
end if;
end process;
 
temp <= (others=>'0');
writeContent <= '0';
writeContentData1 <= (others=>'0');
writeContentData2 <= (others=>'0');
crcReset <= '0';
outboundAck_o <= '0';
-----------------------------------------------------------------------------
-- Packet content generation controller.
-----------------------------------------------------------------------------
stall_o <= writeFrameFull_i when (packetContentReady = '0') else
packetContentPending or packetContentEnd;
controller: process(clk, areset_n)
begin
if (areset_n = '0') then
packetContentReady <= '0';
packetContentPending <= '0';
packetContentLong <= '0';
packetContentOdd <= '0';
elsif (clk'event and clk = '1') then
if (writeFrame = '1') then
packetContentReady <= '0';
packetContentPending <= '0';
packetContentLong <= '0';
packetContentOdd <= adr_i;
elsif (stb_i = '1') and (writeFrameFull_i = '0') then
packetContentOdd <= adr_i;
case packetPosition is
when 2 =>
packetContentReady <= '1';
when 21 =>
packetContentPending <= '1';
packetContentLong <= '1';
when 22 =>
packetContentPending <= '0';
packetContentLong <= '1';
when others =>
end case;
end if;
end if;
end process;
 
writeFrame_o <= '0';
writeFrameAbort_o <= '0';
-----------------------------------------------------------------------------
-- CRC calculation and interface towards the packet queue.
-----------------------------------------------------------------------------
crcCalculation: process(clk, areset_n)
begin
if (areset_n = '0') then
crcCurrent <= x"0000";
elsif (clk'event and clk = '1') then
if (packetContentReady = '0') then
crcCurrent <= x"ffff";
elsif (packetContentReady = '1') then
crcCurrent <= crcNext;
end if;
end if;
end process;
Crc16High: Crc16CITT
port map(
d_i=>packetContent(47 downto 32), crc_i=>crcCurrent, crc_o=>crcTemp);
Crc16Low: Crc16CITT
port map(
d_i=>packetContent(31 downto 16), crc_i=>crcTemp, crc_o=>crcNext);
 
-----------------------------------------------------------------------------
-- Frame buffer output interface.
-----------------------------------------------------------------------------
-- REMARK: This process needs to be optimized further. It is not part of the critical
-- path though.
writeFrameContent: process(clk, areset_n)
variable flush : std_logic;
variable appendCrc : std_ulogic;
variable appendHigh : std_ulogic;
variable endFrame : std_ulogic;
begin
if (areset_n = '0') then
writeFrame <= '0';
writeContent <= '0';
writeFrame_o <= '0';
crcReset <= '0';
case state is
when IDLE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
packetPosition <= 0;
crcReset <= '1';
if (writeFrameFull_i = '0') then
state <= HEADER_GET;
end if;
 
when HEADER_GET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then
temp <= outboundDat_i(15 downto 0);
tt <= outboundDat_i(5 downto 4);
 
outboundAck_o <= '1';
state <= HEADER_ACK;
writeContentData <= (others=>'0');
flush := '0';
appendCrc := '0';
appendHigh := '0';
endFrame := '0';
elsif (clk'event and clk = '1') then
if (writeFrame = '1') then
writeFrame <= '0';
writeContent <= '0';
writeContentData <= (others=>'0');
flush := '0';
appendCrc := '0';
appendHigh := '0';
endFrame := '0';
else
if (flush = '1') then
writeContent <= '1';
writeContentData <= packetContent(47 downto 16);
flush := '0';
elsif (appendCrc = '1') then
writeContent <= '1';
if (appendHigh = '0') then
writeContentData <= packetContent(47 downto 32) & crcTemp;
else
state <= HEADER_GET;
writeContentData <= crcCurrent & x"0000";
end if;
 
when HEADER_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
outboundAck_o <= '0';
state <= DESTINATION_GET;
 
when DESTINATION_GET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then
if (tt = "01") then
writeContentData2 <= temp & outboundDat_i(15 downto 0);
else
report "TT-field not supported." severity error;
end if;
outboundAck_o <= '1';
state <= DESTINATION_ACK;
else
state <= RESTART_FRAME;
end if;
when DESTINATION_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
outboundAck_o <= '0';
state <= SOURCE_GET;
 
when SOURCE_GET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then
if (tt = "01") then
temp <= outboundDat_i(15 downto 0);
end if;
outboundAck_o <= '1';
state <= SOURCE_ACK;
else
state <= RESTART_FRAME;
end if;
when SOURCE_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
outboundAck_o <= '0';
state <= CONTENT_GET;
when CONTENT_GET =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then
if (packetPosition < 19) then
if (tt = "01") then
writeContentData2 <= temp & outboundDat_i(31 downto 16);
temp <= outboundDat_i(15 downto 0);
outboundAck_o <= '1';
end if;
elsif (packetPosition = 19) then
if (tt = "01") then
writeContentData2 <= crc16Next & temp;
end if;
else
if (tt = "01") then
writeContentData2 <= outboundDat_i;
outboundAck_o <= '1';
end if;
end if;
appendCrc := '0';
elsif (endFrame = '1') then
writeContent <= '0';
writeFrame <= '1';
endFrame := '0';
elsif (packetContentPending = '1') and (packetContentEnd = '1') then
writeContent <= '1';
writeContentData <= packetContent(47 downto 16);
flush := not packetContentOdd;
appendCrc := '1';
appendHigh := '1';
endFrame := '1';
elsif (packetContentEnd = '1') then
if (packetContentLong = '0') then
writeContent <= '1';
writeContentData1 <= writeContentData2;
packetPosition <= packetPosition + 1;
state <= CONTENT_ACK;
writeContentData <= packetContent(47 downto 16);
flush := '0';
appendCrc := '1';
appendHigh := packetContentOdd;
endFrame := '1';
else
state <= CRC_APPEND;
end if;
when CONTENT_ACK =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (packetPosition = 20) then
if (tt = "01") then
writeContentData2 <= crc16Next & temp;
end if;
end if;
outboundAck_o <= '0';
state <= CONTENT_GET;
 
when CRC_APPEND =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (packetPosition < 19) then
if (tt = "01") then
if (packetContentOdd = '1') then
writeContent <= '1';
writeContentData1 <= writeContentData2;
packetPosition <= packetPosition + 1;
end if;
elsif (packetPosition = 19) then
if (tt = "01") then
writeContentData <= packetContent(47 downto 32) & crcTemp;
flush := '0';
appendCrc := '0';
appendHigh := '0';
endFrame := '1';
else
writeContent <= '1';
writeContentData1 <= writeContentData2;
packetPosition <= packetPosition + 1;
writeContentData <= packetContent(47 downto 16);
flush := '0';
appendCrc := '1';
appendHigh := '1';
endFrame := '1';
end if;
else
if (tt = "01") then
writeContentData1 <= writeContentData2(31 downto 16) & x"0000";
packetPosition <= packetPosition + 1;
end if;
end if;
state <= CRC_UPDATE;
when CRC_UPDATE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
state <= CRC_LAST;
 
when CRC_LAST =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
if (packetPosition <= 19) then
if (tt = "01") then
writeContent <= '1';
writeContentData1 <= crc16Current & x"0000";
end if;
else
if (tt = "01") then
writeContent <= '1';
writeContentData1 <= writeContentData2(31 downto 16) & crc16Temp;
end if;
end if;
state <= SEND_FRAME;
when SEND_FRAME =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
writeFrame_o <= '1';
state <= WAIT_UPDATE;
 
when RESTART_FRAME =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
writeFrameAbort_o <= '1';
state <= WAIT_UPDATE;
 
when WAIT_UPDATE =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
writeFrameAbort_o <= '0';
state <= IDLE;
when others =>
---------------------------------------------------------------------
--
---------------------------------------------------------------------
end case;
elsif (packetContentReady = '1') then
writeContent <= '1';
writeContentData <= packetContent(47 downto 16);
else
writeContent <= '0';
writeFrame <= '0';
end if;
end if;
end if;
end process;
 
-----------------------------------------------------------------------------
-- Packet CRC calculation.
-----------------------------------------------------------------------------
 
Crc16High: Crc16CITT
port map(
d_i=>writeContentData1(31 downto 16), crc_i=>crc16Current, crc_o=>crc16Temp);
Crc16Low: Crc16CITT
port map(
d_i=>writeContentData1(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next);
 
writeContent_o <= writeContent;
writeFrame_o <= writeFrame;
writeFrameAbort_o <= '0';
writeContentData_o <= writeContentData;
end architecture;
 
 
 
--------------------------------------------------------------------------------
-- RioLogicalCommonInterconnect.
-------------------------------------------------------------------------------
-- RioLogicalCommonIngress.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
818,12 → 666,14
areset_n : in std_logic;
 
stb_i : in std_logic_vector(WIDTH-1 downto 0);
dataM_i : in std_logic_vector(32*WIDTH-1 downto 0);
ack_o : out std_logic_vector(WIDTH-1 downto 0);
adr_i : in std_logic_vector(WIDTH-1 downto 0);
data_i : in std_logic_vector(32*WIDTH-1 downto 0);
stall_o : out std_logic_vector(WIDTH-1 downto 0);
 
stb_o : out std_logic;
dataS_o : out std_logic_vector(31 downto 0);
ack_i : in std_logic);
adr_o : out std_logic;
data_o : out std_logic_vector(31 downto 0);
stall_i : in std_logic);
end entity;
 
 
831,8 → 681,8
-- Architecture for RioLogicalCommonInterconnect.
-------------------------------------------------------------------------------
architecture RioLogicalCommonInterconnectImpl of RioLogicalCommonInterconnect is
signal activeCycle : std_logic;
signal selectedMaster : natural range 0 to WIDTH-1;
signal activeCycle : std_logic := '0';
signal selectedMaster : natural range 0 to WIDTH-1 := 0;
begin
-----------------------------------------------------------------------------
863,10 → 713,11
-- Interconnection.
-----------------------------------------------------------------------------
stb_o <= stb_i(selectedMaster) and activeCycle;
dataS_o <= dataM_i(32*(selectedMaster+1)-1 downto 32*selectedMaster);
adr_o <= adr_i(selectedMaster);
data_o <= data_i(32*(selectedMaster+1)-1 downto 32*selectedMaster);
 
Interconnect: for i in 0 to WIDTH-1 generate
ack_o(i) <= ack_i when (selectedMaster = i) else '0';
stall_o(i) <= stall_i when (selectedMaster = i) and (activeCycle = '1') else '1';
end generate;
 
end architecture;

powered by: WebSVN 2.1.0

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