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