URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio/branches
- from Rev 46 to Rev 47
- ↔ Reverse comparison
Rev 46 → Rev 47
/2.0.0-development/bench/vhdl/TestRioWbBridge.vhd
9,7 → 9,9
-- Contains automatic test code to verify a RioWbBridge implementation. |
-- |
-- To Do: |
-- REMARK: Move the testport package and entities to a seperate file. |
-- - 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. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
43,593 → 45,6
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use work.rio_common.all; |
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
package TestPortPackage is |
constant ADDRESS_WIDTH : natural := 31; |
constant DATA_SIZE_MAX : natural := 32; |
|
type TestPortMessageWishbone is record |
writeAccess : boolean; |
address : std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
byteSelect : std_logic_vector(7 downto 0); |
length : natural range 1 to DATA_SIZE_MAX; |
data : DoublewordArray(0 to DATA_SIZE_MAX-1); |
latency : natural; |
end record; |
|
type TestPortMessageSymbol is record |
symbolType : std_logic_vector(1 downto 0); |
symbolContent : std_logic_vector(31 downto 0); |
ignoreIdle : boolean; |
end record; |
|
type TestPortMessagePacketBuffer is record |
frame : RioFrame; |
willAbort : boolean; |
end record; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
|
component TestPortWishbone is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
messageEmpty_o : out std_logic; |
messageWrite_i : in std_logic; |
message_i : in TestPortMessageWishbone; |
messageAck_o : out std_logic; |
|
cyc_i : in std_logic; |
stb_i : in std_logic; |
we_i : in std_logic; |
adr_i : in std_logic_vector(30 downto 0); |
sel_i : in std_logic_vector(7 downto 0); |
dat_i : in std_logic_vector(63 downto 0); |
dat_o : out std_logic_vector(63 downto 0); |
err_o : out std_logic; |
ack_o : out std_logic); |
end component; |
|
component TestPortPacketBuffer is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
readEmpty_o : out std_logic; |
readWrite_i : in std_logic; |
readMessage_i : in TestPortMessagePacketBuffer; |
readAck_o : out std_logic; |
|
writeEmpty_o : out std_logic; |
writeWrite_i : in std_logic; |
writeMessage_i : in TestPortMessagePacketBuffer; |
writeAck_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readWindowEmpty_o : out std_logic; |
readWindowReset_i : in std_logic; |
readWindowNext_i : in std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
|
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; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortWishboneWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessageWishbone; |
signal ackSignal : in std_logic; |
constant writeAccess : in boolean; |
constant address : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
constant byteSelect : in std_logic_vector(7 downto 0); |
constant length : in natural range 1 to DATA_SIZE_MAX; |
constant data : in DoublewordArray(0 to DATA_SIZE_MAX-1); |
constant latency : natural := 0); |
|
procedure TestPortPacketBufferWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessagePacketBuffer; |
signal ackSignal : in std_logic; |
constant frame : in RioFrame; |
constant willAbort : boolean := false); |
|
end package; |
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
package body TestPortPackage is |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortWishboneWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessageWishbone; |
signal ackSignal : in std_logic; |
constant writeAccess : in boolean; |
constant address : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
constant byteSelect : in std_logic_vector(7 downto 0); |
constant length : in natural range 1 to DATA_SIZE_MAX; |
constant data : in DoublewordArray(0 to DATA_SIZE_MAX-1); |
constant latency : natural := 0) is |
begin |
writeSignal <= '1'; |
messageSignal.writeAccess <= writeAccess; |
messageSignal.address <= address; |
messageSignal.byteSelect <= byteSelect; |
messageSignal.length <= length; |
messageSignal.data <= data; |
messageSignal.latency <= latency; |
wait until ackSignal = '1'; |
writeSignal <= '0'; |
wait until ackSignal = '0'; |
end procedure; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortPacketBufferWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessagePacketBuffer; |
signal ackSignal : in std_logic; |
constant frame : in RioFrame; |
constant willAbort : boolean := false) is |
begin |
writeSignal <= '1'; |
messageSignal.frame <= frame; |
messageSignal.willAbort <= willAbort; |
wait until ackSignal = '1'; |
writeSignal <= '0'; |
wait until ackSignal = '0'; |
end procedure; |
|
end package body; |
|
|
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
library std; |
use std.textio.all; |
use work.rio_common.all; |
use work.TestPortPackage.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity TestPortPacketBuffer is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
readEmpty_o : out std_logic; |
readWrite_i : in std_logic; |
readMessage_i : in TestPortMessagePacketBuffer; |
readAck_o : out std_logic; |
|
writeEmpty_o : out std_logic; |
writeWrite_i : in std_logic; |
writeMessage_i : in TestPortMessagePacketBuffer; |
writeAck_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readWindowEmpty_o : out std_logic; |
readWindowReset_i : in std_logic; |
readWindowNext_i : in std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
|
-- writeFrameFull_o is missing yes, but you can control it from the testbench directly |
-- instead. |
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 TestPortPacketBufferPortImpl of TestPortPacketBuffer is |
constant QUEUE_SIZE : natural := 63; |
type QueueArray is array (natural range <>) of TestPortMessagePacketBuffer; |
|
function QueueIndexInc(constant i : natural) return natural is |
variable returnValue : natural; |
begin |
if(i = QUEUE_SIZE) then |
returnValue := 0; |
else |
returnValue := i + 1; |
end if; |
return returnValue; |
end function; |
|
begin |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Reader: process |
variable frameQueue : QueueArray(0 to QUEUE_SIZE); |
variable front, back, window : natural range 0 to QUEUE_SIZE; |
variable frameIndex : natural; |
begin |
wait until areset_n = '1'; |
|
readFrameEmpty_o <= '1'; |
readFrameAborted_o <= '0'; |
readWindowEmpty_o <= '1'; |
readContentEmpty_o <= '1'; |
readContentEnd_o <= '0'; |
readContentData_o <= (others=>'0'); |
|
front := 0; |
back := 0; |
window := 0; |
frameIndex := 0; |
readEmpty_o <= '1'; |
readAck_o <= '0'; |
|
loop |
wait until clk = '1' or readWrite_i = '1'; |
|
if (clk'event) then |
if (readFrame_i = '1') then |
if (back /= front) then |
back := QueueIndexInc(back); |
else |
TestError("READ:BACK:reading when no frame is present"); |
end if; |
end if; |
|
if (readFrameRestart_i = '1') then |
frameIndex := 0; |
end if; |
|
if (readWindowReset_i = '1') then |
window := back; |
frameIndex := 0; |
end if; |
|
if (readWindowNext_i = '1') then |
if (window /= front) then |
window := QueueIndexInc(window); |
frameIndex := 0; |
else |
TestError("READ:WINDOW:reading when no frame is present"); |
end if; |
end if; |
|
if (readContent_i = '1') then |
if (back /= front) then |
if (frameIndex < frameQueue(window).frame.length) then |
readContentData_o <= frameQueue(window).frame.payload(frameIndex); |
frameIndex := frameIndex + 1; |
if (frameIndex = frameQueue(window).frame.length) then |
readContentEnd_o <= '1'; |
else |
readContentEnd_o <= '0'; |
end if; |
else |
TestError("READ:CONTENT:reading when frame has ended"); |
end if; |
else |
TestError("READ:CONTENT:reading when no frame is present"); |
end if; |
end if; |
|
if (front = back) then |
readFrameEmpty_o <= '1'; |
else |
readFrameEmpty_o <= '0'; |
end if; |
|
if (front = window) then |
readWindowEmpty_o <= '1'; |
readContentEmpty_o <= '1'; |
else |
readWindowEmpty_o <= '0'; |
if (frameIndex /= frameQueue(window).frame.length) then |
readContentEmpty_o <= '0'; |
else |
readContentEmpty_o <= '1'; |
end if; |
end if; |
|
if (front = back) then |
readEmpty_o <= '1'; |
else |
readEmpty_o <= '0'; |
end if; |
elsif (readWrite_i'event) then |
frameQueue(front) := readMessage_i; |
front := QueueIndexInc(front); |
|
readEmpty_o <= '0'; |
readAck_o <= '1'; |
wait until readWrite_i = '0'; |
readAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Writer: process |
variable frameQueue : QueueArray(0 to QUEUE_SIZE); |
variable front, back : natural range 0 to QUEUE_SIZE; |
variable frameIndex : natural range 0 to 69; |
begin |
wait until areset_n = '1'; |
|
writeEmpty_o <= '1'; |
writeAck_o <= '0'; |
|
front := 0; |
back := 0; |
frameIndex := 0; |
|
loop |
wait until clk = '1' or writeWrite_i = '1'; |
|
if (clk'event) then |
|
if (writeFrame_i = '1') then |
if (frameIndex = 0) then |
TestError("WRITE:Empty frame written."); |
end if; |
if (frameIndex /= frameQueue(back).frame.length) then |
TestError("WRITE:Frame with unmatching length was written."); |
end if; |
if (back /= front) then |
back := QueueIndexInc(back); |
else |
TestError("WRITE:Unexpected frame written."); |
end if; |
frameIndex := 0; |
end if; |
|
if (writeFrameAbort_i = '1') then |
if (back /= front) then |
if (frameQueue(back).willAbort) then |
TestCompare(frameIndex, |
frameQueue(back).frame.length, |
"frameIndex abort"); |
back := QueueIndexInc(back); |
else |
TestError("WRITE:Not expecting this frame to abort."); |
end if; |
end if; |
frameIndex := 0; |
end if; |
|
if (writeContent_i = '1') then |
if (frameIndex < frameQueue(back).frame.length) then |
TestCompare(writeContentData_i, |
frameQueue(back).frame.payload(frameIndex), |
"frame content"); |
frameIndex := frameIndex + 1; |
else |
TestError("WRITE:Receiving more frame content than expected."); |
end if; |
end if; |
|
if (front = back) then |
writeEmpty_o <= '1'; |
else |
writeEmpty_o <= '0'; |
end if; |
elsif (writeWrite_i'event) then |
frameQueue(front) := writeMessage_i; |
front := QueueIndexInc(front); |
|
writeEmpty_o <= '0'; |
writeAck_o <= '1'; |
wait until writeWrite_i = '0'; |
writeAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
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; |
use work.TestPortPackage.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity TestPortWishbone is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
messageEmpty_o : out std_logic; |
messageWrite_i : in std_logic; |
message_i : in TestPortMessageWishbone; |
messageAck_o : out std_logic; |
|
cyc_i : in std_logic; |
stb_i : in std_logic; |
we_i : in std_logic; |
adr_i : in std_logic_vector(30 downto 0); |
sel_i : in std_logic_vector(7 downto 0); |
dat_i : in std_logic_vector(63 downto 0); |
dat_o : out std_logic_vector(63 downto 0); |
err_o : out std_logic; |
ack_o : out std_logic); |
end entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture TestPortWishboneImpl of TestPortWishbone is |
constant QUEUE_SIZE : natural := 63; |
type QueueArray is array (natural range <>) of TestPortMessageWishbone; |
|
function QueueIndexInc(constant i : natural) return natural is |
variable returnValue : natural; |
begin |
if(i = QUEUE_SIZE) then |
returnValue := 0; |
else |
returnValue := i + 1; |
end if; |
return returnValue; |
end function; |
|
begin |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Slave: process |
variable queue : QueueArray(0 to QUEUE_SIZE); |
variable front, back : natural range 0 to QUEUE_SIZE; |
variable cyclePosition : natural; |
variable latencyCounter : natural; |
begin |
wait until areset_n = '1'; |
|
messageEmpty_o <= '1'; |
messageAck_o <= '0'; |
|
dat_o <= (others=>'U'); |
err_o <= '0'; |
ack_o <= '0'; |
|
front := 0; |
back := 0; |
cyclePosition := 0; |
latencyCounter := 0; |
|
loop |
wait until clk = '1' or messageWrite_i = '1'; |
|
if (clk'event) then |
if (cyc_i = '1') then |
if (front /= back) then |
if (stb_i = '1') then |
if (latencyCounter <= queue(back).latency) then |
TestCompare(stb_i, '1', "stb_i"); |
if (queue(back).writeAccess) then |
TestCompare(we_i, '1', "we_i"); |
else |
TestCompare(we_i, '0', "we_i"); |
end if; |
TestCompare(adr_i, std_logic_vector(unsigned(queue(back).address)+cyclePosition), "adr_i"); |
TestCompare(sel_i, queue(back).byteSelect, "sel_i"); |
if (queue(back).writeAccess) then |
TestCompare(dat_i, queue(back).data(cyclePosition), "dat_i"); |
end if; |
end if; |
|
if (latencyCounter < queue(back).latency) then |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
latencyCounter := latencyCounter + 1; |
elsif (latencyCounter = queue(back).latency) then |
if (queue(back).writeAccess) then |
dat_o <= (others=>'U'); |
else |
dat_o <= queue(back).data(cyclePosition); |
end if; |
ack_o <= '1'; |
latencyCounter := latencyCounter + 1; |
else |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
latencyCounter := 0; |
cyclePosition := cyclePosition + 1; |
|
if (cyclePosition = queue(back).length) then |
back := QueueIndexInc(back); |
cyclePosition := 0; |
end if; |
end if; |
end if; |
else |
TestError("Unexpected access."); |
end if; |
else |
if (cyclePosition /= 0) or (latencyCounter /= 0) then |
TestError("Cycle unexpectedly aborted."); |
cyclePosition := 0; |
latencyCounter := 0; |
end if; |
TestCompare(stb_i, '0', "stb_i"); |
end if; |
|
if (front = back) then |
messageEmpty_o <= '1'; |
else |
messageEmpty_o <= '0'; |
end if; |
elsif (messageWrite_i'event) then |
queue(front) := message_i; |
front := QueueIndexInc(front); |
|
messageEmpty_o <= '0'; |
messageAck_o <= '1'; |
wait until messageWrite_i = '0'; |
messageAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
end architecture; |
|
|
------------------------------------------------------------------------------- |
-- TestRioWbBridge. |
------------------------------------------------------------------------------- |
|
777,14 → 192,24
-- Procedure to handle wishbone accesses. |
--------------------------------------------------------------------------- |
procedure SetSlaveAccess(constant writeAccess : in boolean; |
constant address : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
constant addressIn : in std_logic_vector(30 downto 0); |
constant byteSelect : in std_logic_vector(7 downto 0); |
constant length : in natural range 1 to DATA_SIZE_MAX; |
constant data : in DoublewordArray(0 to DATA_SIZE_MAX-1); |
constant length : in natural range 1 to 32; |
constant dataIn : in DoublewordArray(0 to 31); |
constant latency : natural := 1) is |
variable address : std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0); |
begin |
TestPortWishboneWrite(wbMessageWrite, wbMessage, wbMessageAck, |
writeAccess, address, byteSelect, length, data, latency); |
address := x"00000000" & '0' & addressIn; |
for i in 0 to length-1 loop |
if (i = (length-1)) then |
TestPortWishboneWrite(wbMessageWrite, wbMessage, wbMessageAck, |
writeAccess, address, byteSelect, dataIn(i), false, latency); |
else |
TestPortWishboneWrite(wbMessageWrite, wbMessage, wbMessageAck, |
writeAccess, address, byteSelect, dataIn(i), true, latency); |
address := std_logic_vector(unsigned(address)+1); |
end if; |
end loop; |
end procedure; |
|
--------------------------------------------------------------------------- |
1011,7 → 436,7
if (j = 0) then |
wdptr := '0'; |
else |
wdptr:= '1'; |
wdptr := '1'; |
end if; |
|
CreateRandomPayload(ioData, seed1, seed2); |
1059,6 → 484,7
PrintR("TG_RioWbBridge-TC3-Step1"); |
--------------------------------------------------------------------------- |
-- REMARK: Change the address and tid also... |
-- REMARK: Not really all sizes, add sizes in between the fixed as well. |
for i in 0 to 15 loop |
for j in 0 to 1 loop |
wrsize := std_logic_vector(to_unsigned(i, 4)); |
1065,7 → 491,7
if (j = 0) then |
wdptr := '0'; |
else |
wdptr:= '1'; |
wdptr := '1'; |
end if; |
|
CreateRandomPayload(ioData, seed1, seed2); |
1190,6 → 616,7
----------------------------------------------------------------------------- |
|
TestPortPacketBufferInst: TestPortPacketBuffer |
generic map(READ_CONTENT_END_DATA_VALID=>false) |
port map( |
clk=>clk, areset_n=>areset_n, |
readEmpty_o=>inboundEmpty, |
/2.0.0-development/bench/vhdl/TestPortPackage.vhd
0,0 → 1,659
------------------------------------------------------------------------------- |
-- |
-- RapidIO IP Library Core |
-- |
-- This file is part of the RapidIO IP library project |
-- http://www.opencores.org/cores/rio/ |
-- |
-- Description |
-- Contains components that can simulate various interfaces used in the RapidIO |
-- IP library project. |
-- |
-- To Do: |
-- - Add Symbol-testport from TestRioSerial here. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2013 Authors and OPENCORES.ORG |
-- |
-- This source file may be used and distributed without |
-- restriction provided that this copyright statement is not |
-- removed from the file and that any derivative work contains |
-- the original copyright notice and the associated disclaimer. |
-- |
-- This source file is free software; you can redistribute it |
-- and/or modify it under the terms of the GNU Lesser General |
-- Public License as published by the Free Software Foundation; |
-- either version 2.1 of the License, or (at your option) any |
-- later version. |
-- |
-- This source is distributed in the hope that it will be |
-- useful, but WITHOUT ANY WARRANTY; without even the implied |
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
-- PURPOSE. See the GNU Lesser General Public License for more |
-- details. |
-- |
-- You should have received a copy of the GNU Lesser General |
-- Public License along with this source; if not, download it |
-- from http://www.opencores.org/lgpl.shtml |
-- |
------------------------------------------------------------------------------- |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use work.rio_common.all; |
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
package TestPortPackage is |
constant ADDRESS_WIDTH_MAX : natural := 64; |
constant DATA_WIDTH_MAX : natural := 64; |
constant SEL_WIDTH_MAX : natural := 8; |
|
type TestPortMessageWishbone is record |
writeAccess : boolean; |
address : std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0); |
byteSelect : std_logic_vector(SEL_WIDTH_MAX-1 downto 0); |
data : std_logic_vector(DATA_WIDTH_MAX-1 downto 0); |
continue : boolean; |
latency : natural; |
end record; |
type TestPortMessageWishboneArray is |
array (natural range <>) of TestPortMessageWishbone; |
|
type TestPortMessageSymbol is record |
symbolType : std_logic_vector(1 downto 0); |
symbolContent : std_logic_vector(31 downto 0); |
ignoreIdle : boolean; |
end record; |
type TestPortMessageSymbolArray is |
array (natural range <>) of TestPortMessageSymbol; |
|
type TestPortMessagePacketBuffer is record |
frame : RioFrame; |
willAbort : boolean; |
end record; |
type TestPortMessagePacketBufferArray is |
array (natural range <>) of TestPortMessagePacketBuffer; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
|
component TestPortWishbone is |
generic( |
ADDRESS_WIDTH : natural := 31; |
SEL_WIDTH : natural := 8; |
DATA_WIDTH : natural := 64); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
messageEmpty_o : out std_logic; |
messageWrite_i : in std_logic; |
message_i : in TestPortMessageWishbone; |
messageAck_o : out std_logic; |
|
cyc_i : in std_logic; |
stb_i : in std_logic; |
we_i : in std_logic; |
adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0); |
dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0); |
dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0); |
err_o : out std_logic; |
ack_o : out std_logic); |
end component; |
|
component TestPortPacketBuffer is |
generic( |
READ_CONTENT_END_DATA_VALID : boolean := true); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
readEmpty_o : out std_logic; |
readWrite_i : in std_logic; |
readMessage_i : in TestPortMessagePacketBuffer; |
readAck_o : out std_logic; |
|
writeEmpty_o : out std_logic; |
writeWrite_i : in std_logic; |
writeMessage_i : in TestPortMessagePacketBuffer; |
writeAck_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readWindowEmpty_o : out std_logic; |
readWindowReset_i : in std_logic; |
readWindowNext_i : in std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
|
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; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortWishboneWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessageWishbone; |
signal ackSignal : in std_logic; |
constant writeAccess : in boolean; |
constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0); |
constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0); |
constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0); |
constant continue : in boolean := false; |
constant latency : in natural := 0); |
|
procedure TestPortPacketBufferWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessagePacketBuffer; |
signal ackSignal : in std_logic; |
constant frame : in RioFrame; |
constant willAbort : in boolean := false); |
|
end package; |
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
package body TestPortPackage is |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortWishboneWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessageWishbone; |
signal ackSignal : in std_logic; |
constant writeAccess : in boolean; |
constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0); |
constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0); |
constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0); |
constant continue : in boolean := false; |
constant latency : in natural := 0) is |
begin |
writeSignal <= '1'; |
messageSignal.writeAccess <= writeAccess; |
messageSignal.address <= address; |
messageSignal.byteSelect <= byteSelect; |
messageSignal.data <= data; |
messageSignal.continue <= continue; |
messageSignal.latency <= latency; |
wait until ackSignal = '1'; |
writeSignal <= '0'; |
wait until ackSignal = '0'; |
end procedure; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
procedure TestPortPacketBufferWrite( |
signal writeSignal : out std_logic; |
signal messageSignal : out TestPortMessagePacketBuffer; |
signal ackSignal : in std_logic; |
constant frame : in RioFrame; |
constant willAbort : in boolean := false) is |
begin |
writeSignal <= '1'; |
messageSignal.frame <= frame; |
messageSignal.willAbort <= willAbort; |
wait until ackSignal = '1'; |
writeSignal <= '0'; |
wait until ackSignal = '0'; |
end procedure; |
|
end package body; |
|
|
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
library std; |
use std.textio.all; |
use work.rio_common.all; |
use work.TestPortPackage.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity TestPortPacketBuffer is |
generic( |
READ_CONTENT_END_DATA_VALID : boolean := true); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
readEmpty_o : out std_logic; |
readWrite_i : in std_logic; |
readMessage_i : in TestPortMessagePacketBuffer; |
readAck_o : out std_logic; |
|
writeEmpty_o : out std_logic; |
writeWrite_i : in std_logic; |
writeMessage_i : in TestPortMessagePacketBuffer; |
writeAck_o : out std_logic; |
|
readFrameEmpty_o : out std_logic; |
readFrame_i : in std_logic; |
readFrameRestart_i : in std_logic; |
readFrameAborted_o : out std_logic; |
readWindowEmpty_o : out std_logic; |
readWindowReset_i : in std_logic; |
readWindowNext_i : in std_logic; |
readContentEmpty_o : out std_logic; |
readContent_i : in std_logic; |
readContentEnd_o : out std_logic; |
readContentData_o : out std_logic_vector(31 downto 0); |
|
-- writeFrameFull_o is missing yes, but you can control it from the testbench directly |
-- instead. |
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 TestPortPacketBufferPortImpl of TestPortPacketBuffer is |
constant QUEUE_SIZE : natural := 63; |
type QueueArray is array (natural range <>) of TestPortMessagePacketBuffer; |
|
function QueueIndexInc(constant i : natural) return natural is |
variable returnValue : natural; |
begin |
if(i = QUEUE_SIZE) then |
returnValue := 0; |
else |
returnValue := i + 1; |
end if; |
return returnValue; |
end function; |
|
begin |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Reader: process |
variable frameQueue : QueueArray(0 to QUEUE_SIZE); |
variable front, back, window : natural range 0 to QUEUE_SIZE; |
variable frameIndex : natural; |
begin |
wait until areset_n = '1'; |
|
readFrameEmpty_o <= '1'; |
readFrameAborted_o <= '0'; |
readWindowEmpty_o <= '1'; |
readContentEmpty_o <= '1'; |
readContentEnd_o <= '0'; |
readContentData_o <= (others=>'0'); |
|
front := 0; |
back := 0; |
window := 0; |
frameIndex := 0; |
readEmpty_o <= '1'; |
readAck_o <= '0'; |
|
loop |
wait until clk = '1' or readWrite_i = '1'; |
|
if (clk'event) then |
if (readFrame_i = '1') then |
if (back /= front) then |
back := QueueIndexInc(back); |
else |
TestError("READ:BACK:reading when no frame is present"); |
end if; |
end if; |
|
if (readFrameRestart_i = '1') then |
frameIndex := 0; |
end if; |
|
if (readWindowReset_i = '1') then |
window := back; |
frameIndex := 0; |
end if; |
|
if (readWindowNext_i = '1') then |
if (window /= front) then |
window := QueueIndexInc(window); |
frameIndex := 0; |
else |
TestError("READ:WINDOW:reading when no frame is present"); |
end if; |
end if; |
|
if (readContent_i = '1') then |
if (back /= front) then |
if (READ_CONTENT_END_DATA_VALID) then |
if (frameIndex < frameQueue(window).frame.length) then |
readContentData_o <= frameQueue(window).frame.payload(frameIndex); |
frameIndex := frameIndex + 1; |
if (frameIndex = frameQueue(window).frame.length) then |
readContentEnd_o <= '1'; |
else |
readContentEnd_o <= '0'; |
end if; |
else |
TestError("READ:CONTENT:reading when frame has ended"); |
end if; |
else |
if (frameIndex < frameQueue(window).frame.length) then |
readContentData_o <= frameQueue(window).frame.payload(frameIndex); |
readContentEnd_o <= '0'; |
frameIndex := frameIndex + 1; |
elsif (frameIndex = frameQueue(window).frame.length) then |
readContentData_o <= (others=>'U'); |
readContentEnd_o <= '1'; |
else |
TestError("READ:CONTENT:reading when frame has ended"); |
end if; |
end if; |
else |
TestError("READ:CONTENT:reading when no frame is present"); |
end if; |
end if; |
|
if (front = back) then |
readFrameEmpty_o <= '1'; |
else |
readFrameEmpty_o <= '0'; |
end if; |
|
if (front = window) then |
readWindowEmpty_o <= '1'; |
readContentEmpty_o <= '1'; |
else |
readWindowEmpty_o <= '0'; |
if (frameIndex /= frameQueue(window).frame.length) then |
readContentEmpty_o <= '0'; |
else |
readContentEmpty_o <= '1'; |
end if; |
end if; |
|
if (front = back) then |
readEmpty_o <= '1'; |
else |
readEmpty_o <= '0'; |
end if; |
elsif (readWrite_i'event) then |
frameQueue(front) := readMessage_i; |
front := QueueIndexInc(front); |
|
readEmpty_o <= '0'; |
readAck_o <= '1'; |
wait until readWrite_i = '0'; |
readAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Writer: process |
variable frameQueue : QueueArray(0 to QUEUE_SIZE); |
variable front, back : natural range 0 to QUEUE_SIZE; |
variable frameIndex : natural range 0 to 69; |
begin |
wait until areset_n = '1'; |
|
writeEmpty_o <= '1'; |
writeAck_o <= '0'; |
|
front := 0; |
back := 0; |
frameIndex := 0; |
|
loop |
wait until clk = '1' or writeWrite_i = '1'; |
|
if (clk'event) then |
|
if (writeFrame_i = '1') then |
if (frameIndex = 0) then |
TestError("WRITE:Empty frame written."); |
end if; |
if (frameIndex /= frameQueue(back).frame.length) then |
TestError("WRITE:Frame with unmatching length was written."); |
end if; |
if (back /= front) then |
back := QueueIndexInc(back); |
else |
TestError("WRITE:Unexpected frame written."); |
end if; |
frameIndex := 0; |
end if; |
|
if (writeFrameAbort_i = '1') then |
if (back /= front) then |
if (frameQueue(back).willAbort) then |
TestCompare(frameIndex, |
frameQueue(back).frame.length, |
"frameIndex abort"); |
back := QueueIndexInc(back); |
else |
TestError("WRITE:Not expecting this frame to abort."); |
end if; |
end if; |
frameIndex := 0; |
end if; |
|
if (writeContent_i = '1') then |
if (frameIndex < frameQueue(back).frame.length) then |
TestCompare(writeContentData_i, |
frameQueue(back).frame.payload(frameIndex), |
"frame content"); |
frameIndex := frameIndex + 1; |
else |
TestError("WRITE:Receiving more frame content than expected."); |
end if; |
end if; |
|
if (front = back) then |
writeEmpty_o <= '1'; |
else |
writeEmpty_o <= '0'; |
end if; |
elsif (writeWrite_i'event) then |
frameQueue(front) := writeMessage_i; |
front := QueueIndexInc(front); |
|
writeEmpty_o <= '0'; |
writeAck_o <= '1'; |
wait until writeWrite_i = '0'; |
writeAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
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; |
use work.TestPortPackage.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity TestPortWishbone is |
generic( |
ADDRESS_WIDTH : natural := 31; |
SEL_WIDTH : natural := 8; |
DATA_WIDTH : natural := 64); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
messageEmpty_o : out std_logic; |
messageWrite_i : in std_logic; |
message_i : in TestPortMessageWishbone; |
messageAck_o : out std_logic; |
|
cyc_i : in std_logic; |
stb_i : in std_logic; |
we_i : in std_logic; |
adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0); |
dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0); |
dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0); |
err_o : out std_logic; |
ack_o : out std_logic); |
end entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture TestPortWishboneImpl of TestPortWishbone is |
constant QUEUE_SIZE : natural := 63; |
type QueueArray is array (natural range <>) of TestPortMessageWishbone; |
|
function QueueIndexInc(constant i : natural) return natural is |
variable returnValue : natural; |
begin |
if(i = QUEUE_SIZE) then |
returnValue := 0; |
else |
returnValue := i + 1; |
end if; |
return returnValue; |
end function; |
|
begin |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Slave: process |
variable queue : QueueArray(0 to QUEUE_SIZE); |
variable front, back : natural range 0 to QUEUE_SIZE; |
variable latencyCounter : natural; |
variable activeCycle : boolean; |
begin |
wait until areset_n = '1'; |
|
messageEmpty_o <= '1'; |
messageAck_o <= '0'; |
|
dat_o <= (others=>'U'); |
err_o <= '0'; |
ack_o <= '0'; |
|
front := 0; |
back := 0; |
latencyCounter := 0; |
activeCycle := false; |
|
loop |
wait until clk = '1' or messageWrite_i = '1'; |
|
if (clk'event) then |
if (cyc_i = '1') then |
if (front /= back) then |
if (stb_i = '1') then |
if (latencyCounter <= queue(back).latency) then |
TestCompare(stb_i, '1', "stb_i"); |
if (queue(back).writeAccess) then |
TestCompare(we_i, '1', "we_i"); |
else |
TestCompare(we_i, '0', "we_i"); |
end if; |
TestCompare(adr_i, queue(back).address(ADDRESS_WIDTH-1 downto 0), "adr_i"); |
TestCompare(sel_i, queue(back).byteSelect(SEL_WIDTH-1 downto 0), "sel_i"); |
if (queue(back).writeAccess) then |
TestCompare(dat_i, queue(back).data(DATA_WIDTH-1 downto 0), "dat_i"); |
end if; |
end if; |
|
if (latencyCounter < queue(back).latency) then |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
latencyCounter := latencyCounter + 1; |
elsif (latencyCounter = queue(back).latency) then |
if (queue(back).writeAccess) then |
dat_o <= (others=>'U'); |
else |
dat_o <= queue(back).data(DATA_WIDTH-1 downto 0); |
end if; |
ack_o <= '1'; |
latencyCounter := latencyCounter + 1; |
else |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
latencyCounter := 0; |
activeCycle := queue(back).continue; |
back := QueueIndexInc(back); |
end if; |
end if; |
else |
TestError("Unexpected access."); |
end if; |
else |
if (activeCycle or (latencyCounter /= 0)) then |
TestError("Cycle unexpectedly aborted."); |
latencyCounter := 0; |
end if; |
TestCompare(stb_i, '0', "stb_i"); |
end if; |
|
if (front = back) then |
messageEmpty_o <= '1'; |
else |
messageEmpty_o <= '0'; |
end if; |
elsif (messageWrite_i'event) then |
queue(front) := message_i; |
front := QueueIndexInc(front); |
|
messageEmpty_o <= '0'; |
messageAck_o <= '1'; |
wait until messageWrite_i = '0'; |
messageAck_o <= '0'; |
end if; |
end loop; |
end process; |
|
end architecture; |
|
|
/2.0.0-development/bench/vhdl/TestRioSwitch.vhd
9,7 → 9,8
-- 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): |
-- - Magnus Rosenius, magro732@opencores.org |
53,6 → 54,7
library std; |
use std.textio.all; |
use work.rio_common.all; |
use work.TestPortPackage.all; |
|
|
------------------------------------------------------------------------------- |
114,38 → 116,11
configWe_o : out std_logic; |
configAddr_o : out std_logic_vector(23 downto 0); |
configData_o : out std_logic_vector(31 downto 0); |
configData_i : in std_logic_vector(31 downto 0)); |
configData_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; |
|
constant PORTS : natural := 7; |
constant PORTS : natural := 3; |
constant SWITCH_IDENTITY : std_logic_vector(15 downto 0) := x"0123"; |
constant SWITCH_VENDOR_IDENTITY : std_logic_vector(15 downto 0) := x"4567"; |
constant SWITCH_REV : std_logic_vector(31 downto 0) := x"89abcdef"; |
156,14 → 131,40
signal clk : std_logic; |
signal areset_n : std_logic; |
|
signal frameValid : Array1(PORTS-1 downto 0); |
signal frameWrite : RioFrameArray(PORTS-1 downto 0); |
signal frameComplete : Array1(PORTS-1 downto 0); |
|
signal frameExpected : Array1(PORTS-1 downto 0); |
signal frameRead : RioFrameArray(PORTS-1 downto 0); |
signal frameReceived : Array1(PORTS-1 downto 0); |
signal inboundEmpty : Array1(PORTS-1 downto 0); |
signal inboundEmpty0 : std_logic; |
signal inboundEmpty1 : std_logic; |
signal inboundEmpty2 : std_logic; |
signal inboundWrite : Array1(PORTS-1 downto 0); |
signal inboundWrite0 : std_logic; |
signal inboundWrite1 : std_logic; |
signal inboundWrite2 : std_logic; |
signal inboundMessage : TestPortMessagePacketBufferArray(PORTS-1 downto 0); |
signal inboundMessage0 : TestPortMessagePacketBuffer; |
signal inboundMessage1 : TestPortMessagePacketBuffer; |
signal inboundMessage2 : TestPortMessagePacketBuffer; |
signal inboundAck : Array1(PORTS-1 downto 0); |
signal inboundAck0 : std_logic; |
signal inboundAck1 : std_logic; |
signal inboundAck2 : std_logic; |
|
signal outboundEmpty : Array1(PORTS-1 downto 0); |
signal outboundEmpty0 : std_logic; |
signal outboundEmpty1 : std_logic; |
signal outboundEmpty2 : std_logic; |
signal outboundWrite : Array1(PORTS-1 downto 0); |
signal outboundWrite0 : std_logic; |
signal outboundWrite1 : std_logic; |
signal outboundWrite2 : std_logic; |
signal outboundMessage : TestPortMessagePacketBufferArray(PORTS-1 downto 0); |
signal outboundMessage0 : TestPortMessagePacketBuffer; |
signal outboundMessage1 : TestPortMessagePacketBuffer; |
signal outboundMessage2 : TestPortMessagePacketBuffer; |
signal outboundAck : Array1(PORTS-1 downto 0); |
signal outboundAck0 : std_logic; |
signal outboundAck1 : std_logic; |
signal outboundAck2 : std_logic; |
|
signal writeFrameFull : Array1(PORTS-1 downto 0); |
signal writeFrame : Array1(PORTS-1 downto 0); |
signal writeFrameAbort : Array1(PORTS-1 downto 0); |
194,11 → 195,17
signal outstandingAckIdRead : Array5(PORTS-1 downto 0); |
signal outboundAckIdRead : Array5(PORTS-1 downto 0); |
|
signal configStb, configStbExpected : std_logic; |
signal configWe, configWeExpected : std_logic; |
signal configAddr, configAddrExpected : std_logic_vector(23 downto 0); |
signal configDataWrite, configDataWriteExpected : std_logic_vector(31 downto 0); |
signal configDataRead, configDataReadExpected : std_logic_vector(31 downto 0); |
signal messageEmpty : std_logic; |
signal messageWrite : std_logic; |
signal message : TestPortMessageWishbone; |
signal messageAck : std_logic; |
|
signal configStb : std_logic; |
signal configWe : std_logic; |
signal configAddr : std_logic_vector(23 downto 0); |
signal configDataWrite : std_logic_vector(31 downto 0); |
signal configDataRead : std_logic_vector(31 downto 0); |
signal configAck : std_logic; |
|
begin |
|
225,10 → 232,18
procedure SendFrame(constant portIndex : natural range 0 to 7; |
constant frame : RioFrame) is |
begin |
frameValid(portIndex) <= '1'; |
frameWrite(portIndex) <= frame; |
wait until frameComplete(portIndex) = '1'; |
frameValid(portIndex) <= '0'; |
-- Crappy Modelsim cannot handle arrays of signals... |
case portIndex is |
when 0 => |
TestPortPacketBufferWrite(inboundWrite0, inboundMessage0, inboundAck0, |
frame, false); |
when 1 => |
TestPortPacketBufferWrite(inboundWrite1, inboundMessage1, inboundAck1, |
frame, false); |
when others => |
TestPortPacketBufferWrite(inboundWrite2, inboundMessage2, inboundAck2, |
frame, false); |
end case; |
end procedure; |
|
--------------------------------------------------------------------------- |
237,15 → 252,55
procedure ReceiveFrame(constant portIndex : natural range 0 to 7; |
constant frame : RioFrame) is |
begin |
frameExpected(portIndex) <= '1'; |
frameRead(portIndex) <= frame; |
wait until frameReceived(portIndex) = '1'; |
frameExpected(portIndex) <= '0'; |
-- Crappy Modelsim cannot handle arrays of signals... |
case portIndex is |
when 0 => |
TestPortPacketBufferWrite(outboundWrite0, outboundMessage0, outboundAck0, |
frame, false); |
when 1 => |
TestPortPacketBufferWrite(outboundWrite1, outboundMessage1, outboundAck1, |
frame, false); |
when others => |
TestPortPacketBufferWrite(outboundWrite2, outboundMessage2, outboundAck2, |
frame, false); |
end case; |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure SendFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
SendFrame(portIndex, frame); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReceiveFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
ReceiveFrame(portIndex, frame); |
end procedure; |
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReadConfig32(constant portIndex : natural range 0 to 7; |
constant destinationId : std_logic_vector(15 downto 0); |
constant sourceId : std_logic_vector(15 downto 0); |
340,67 → 395,64
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
destId=>destinationId, sourceId=>sourceId, |
payload=>payload); |
|
frameExpected(destinationPortIndex) <= '1'; |
frameRead(destinationPortIndex) <= frame; |
|
frameValid(sourcePortIndex) <= '1'; |
frameWrite(sourcePortIndex) <= frame; |
wait until frameComplete(sourcePortIndex) = '1'; |
frameValid(sourcePortIndex) <= '0'; |
|
wait until frameReceived(destinationPortIndex) = '1'; |
frameExpected(destinationPortIndex) <= '0'; |
|
ReceiveFrame(destinationPortIndex, frame); |
SendFrame(sourcePortIndex, frame); |
end procedure; |
|
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure SendFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
procedure ExchangeFrames is |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
|
frameValid(portIndex) <= '1'; |
frameWrite(portIndex) <= frame; |
TestWait(inboundEmpty0, '1', "port0 frame sent"); |
TestWait(inboundEmpty1, '1', "port0 frame sent"); |
TestWait(inboundEmpty2, '1', "port0 frame sent"); |
TestWait(outboundEmpty0, '1', "port0 frame received"); |
TestWait(outboundEmpty1, '1', "port0 frame received"); |
TestWait(outboundEmpty2, '1', "port0 frame received"); |
end procedure; |
|
|
--------------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------------- |
procedure ReceiveFrame(constant portIndex : natural range 0 to 7; |
constant sourceId : std_logic_vector(15 downto 0); |
constant destinationId : std_logic_vector(15 downto 0); |
constant payload : RioPayload) is |
variable frame : RioFrame; |
procedure ConfigRead(constant address : std_logic_vector(23 downto 0); |
constant data : std_logic_vector(31 downto 0)) is |
begin |
frame := RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>"0000", |
sourceId=>sourceId, destId=>destinationId, |
payload=>payload); |
|
frameExpected(portIndex) <= '1'; |
frameRead(portIndex) <= frame; |
TestPortWishboneWrite(writeSignal=>messageWrite, |
messageSignal=>message, |
ackSignal=>messageAck, |
writeAccess=>false, |
address=>(x"00000000" & x"00" & address), |
byteSelect=>x"00", |
data=>(x"00000000" & data), |
latency=>3); |
end procedure; |
|
procedure ConfigWrite(constant address : std_logic_vector(23 downto 0); |
constant data : std_logic_vector(31 downto 0)) is |
begin |
TestPortWishboneWrite(writeSignal=>messageWrite, |
messageSignal=>message, |
ackSignal=>messageAck, |
writeAccess=>true, |
address=>(x"00000000" & x"00" & address), |
byteSelect=>x"00", |
data=>(x"00000000" & data), |
latency=>3); |
end procedure; |
|
-- These variabels are needed for the random number generation. |
variable seed1 : positive := 1; |
variable seed2: positive := 1; |
|
variable maintData : DoubleWordArray(0 to 7); |
variable data : DoubleWordArray(0 to 31); |
variable randomPayload : RioPayload; |
variable randomPayload1 : RioPayload; |
variable randomPayload2 : RioPayload; |
variable frame : RioFrameArray(0 to PORTS-1); |
variable frame : RioFrame; |
|
begin |
areset_n <= '0'; |
407,9 → 459,14
|
linkInitialized <= (others=>'0'); |
|
writeFrameFull <= (others=>'0'); |
for portIndex in 0 to PORTS-1 loop |
frameValid(portIndex) <= '0'; |
frameExpected(portIndex) <= '0'; |
inboundWrite0 <= '0'; |
outboundWrite0 <= '0'; |
inboundWrite1 <= '0'; |
outboundWrite1 <= '0'; |
inboundWrite2 <= '0'; |
outboundWrite2 <= '0'; |
localAckIdWrite(portIndex) <= '0'; |
clrOutstandingAckId(portIndex) <= '0'; |
inboundAckIdWrite(portIndex) <= (others=>'0'); |
447,6 → 504,8
ReadConfig32(portIndex=>3, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"03", address=>x"00000c", data=>(SWITCH_ASSY_REV & x"0100")); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
462,6 → 521,8
ReadConfig32(portIndex=>4, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"04", address=>x"000010", data=>x"10000118"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 3:"); |
471,9 → 532,11
PrintR("TG_RioSwitch-TC1-Step3"); |
--------------------------------------------------------------------------- |
|
ReadConfig32(portIndex=>5, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"05", address=>x"000014", data=>x"00000705"); |
ReadConfig32(portIndex=>2, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"05", address=>x"000014", data=>x"00000302"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 4:"); |
486,6 → 549,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000034", data=>x"00000800"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 5:"); |
540,6 → 605,8
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"00", address=>x"000068", data=>x"0000ffff"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 6"); |
558,6 → 625,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00006c", data=>x"ffffffff"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 7"); |
578,6 → 647,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000120", data=>x"00000100"); |
|
ExchangeFrames; |
|
assert portLinkTimeout = x"000001" report "Unexpected portLinkTimeout." severity error; |
|
--------------------------------------------------------------------------- |
604,6 → 675,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00013c", data=>x"00000000"); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 9"); |
616,52 → 689,30
linkInitialized(0) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000158", data=>x"00000001"); |
ExchangeFrames; |
linkInitialized(0) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000158", data=>x"00000002"); |
ExchangeFrames; |
|
linkInitialized(1) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000178", data=>x"00000001"); |
ExchangeFrames; |
linkInitialized(1) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000178", data=>x"00000002"); |
ExchangeFrames; |
|
linkInitialized(2) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000198", data=>x"00000001"); |
ExchangeFrames; |
linkInitialized(2) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000198", data=>x"00000002"); |
ExchangeFrames; |
|
linkInitialized(3) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001b8", data=>x"00000001"); |
linkInitialized(3) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001b8", data=>x"00000002"); |
|
linkInitialized(4) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001d8", data=>x"00000001"); |
linkInitialized(4) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001d8", data=>x"00000002"); |
|
linkInitialized(5) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001f8", data=>x"00000001"); |
linkInitialized(5) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001f8", data=>x"00000002"); |
|
linkInitialized(6) <= '0'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000218", data=>x"00000001"); |
linkInitialized(6) <= '1'; |
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"000218", data=>x"00000002"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 10"); |
683,6 → 734,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00015c", data=>x"00600001"); |
|
ExchangeFrames; |
|
assert outputPortEnable(0) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(0) = '1' report "Unexpected inputPortEnable." severity error; |
|
700,6 → 753,8
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00017c", data=>x"00600001"); |
|
ExchangeFrames; |
|
assert outputPortEnable(1) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(1) = '1' report "Unexpected inputPortEnable." severity error; |
|
717,78 → 772,12
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00019c", data=>x"00600001"); |
|
ExchangeFrames; |
|
assert outputPortEnable(2) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(2) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(3) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(3) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001bc", data=>x"00600001"); |
|
assert outputPortEnable(3) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(3) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(4) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(4) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001dc", data=>x"00600001"); |
|
assert outputPortEnable(4) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(4) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(5) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(5) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"0001fc", data=>x"00600001"); |
|
assert outputPortEnable(5) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(5) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
|
assert outputPortEnable(6) = '0' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(6) = '0' report "Unexpected inputPortEnable." severity error; |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00000001"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00600001"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"00021c", data=>x"00600001"); |
|
assert outputPortEnable(6) = '1' report "Unexpected outputPortEnable." severity error; |
assert inputPortEnable(6) = '1' report "Unexpected inputPortEnable." severity error; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 11"); |
PrintS("Action: Read and write to/from the implementation defined space."); |
797,22 → 786,96
PrintR("TG_RioSwitch-TC1-Step11"); |
--------------------------------------------------------------------------- |
|
configStbExpected <= '1'; |
configWeExpected <= '0'; |
configAddrExpected <= x"010000"; |
configDataReadExpected <= x"deadbeef"; |
CreateRandomPayload(maintData, seed1, seed2); |
ConfigRead(x"010000", maintData(0)(63 downto 32)); |
ConfigRead(x"010004", maintData(0)(31 downto 0)); |
ConfigRead(x"010008", maintData(1)(63 downto 32)); |
ConfigRead(x"01000c", maintData(1)(31 downto 0)); |
ConfigRead(x"010010", maintData(2)(63 downto 32)); |
ConfigRead(x"010014", maintData(2)(31 downto 0)); |
ConfigRead(x"010018", maintData(3)(63 downto 32)); |
ConfigRead(x"01001c", maintData(3)(31 downto 0)); |
ConfigRead(x"010020", maintData(4)(63 downto 32)); |
ConfigRead(x"010024", maintData(4)(31 downto 0)); |
ConfigRead(x"010028", maintData(5)(63 downto 32)); |
ConfigRead(x"01002c", maintData(5)(31 downto 0)); |
ConfigRead(x"010030", maintData(6)(63 downto 32)); |
ConfigRead(x"010034", maintData(6)(31 downto 0)); |
ConfigRead(x"010038", maintData(7)(63 downto 32)); |
ConfigRead(x"01003c", maintData(7)(31 downto 0)); |
|
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0000", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000010000000000000", |
wdptr=>'1', |
dataLength=>0, |
data=>maintData))); |
|
ReceiveFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"dead", sourceId=>x"0000", |
payload=>RioMaintenance(transaction=>"0010", |
size=>"0000", |
tid=>x"ef", |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>8, |
data=>maintData))); |
|
ExchangeFrames; |
TestWait(messageEmpty, '1', "config read"); |
|
ReadConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"010000", data=>x"deadbeef"); |
CreateRandomPayload(maintData, seed1, seed2); |
ConfigWrite(x"010000", maintData(0)(63 downto 32)); |
ConfigWrite(x"010004", maintData(0)(31 downto 0)); |
ConfigWrite(x"010008", maintData(1)(63 downto 32)); |
ConfigWrite(x"01000c", maintData(1)(31 downto 0)); |
ConfigWrite(x"010010", maintData(2)(63 downto 32)); |
ConfigWrite(x"010014", maintData(2)(31 downto 0)); |
ConfigWrite(x"010018", maintData(3)(63 downto 32)); |
ConfigWrite(x"01001c", maintData(3)(31 downto 0)); |
ConfigWrite(x"010020", maintData(4)(63 downto 32)); |
ConfigWrite(x"010024", maintData(4)(31 downto 0)); |
ConfigWrite(x"010028", maintData(5)(63 downto 32)); |
ConfigWrite(x"01002c", maintData(5)(31 downto 0)); |
ConfigWrite(x"010030", maintData(6)(63 downto 32)); |
ConfigWrite(x"010034", maintData(6)(31 downto 0)); |
ConfigWrite(x"010038", maintData(7)(63 downto 32)); |
ConfigWrite(x"01003c", maintData(7)(31 downto 0)); |
|
configStbExpected <= '1'; |
configWeExpected <= '1'; |
configAddrExpected <= x"010004"; |
configDataWriteExpected <= x"c0debabe"; |
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0001", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000010000000000000", |
wdptr=>'1', |
dataLength=>8, |
data=>maintData))); |
|
ReceiveFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"dead", sourceId=>x"0000", |
payload=>RioMaintenance(transaction=>"0011", |
size=>"0000", |
tid=>x"ef", |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
ExchangeFrames; |
TestWait(messageEmpty, '1', "config read"); |
|
WriteConfig32(portIndex=>6, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"06", address=>x"010004", data=>x"c0debabe"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch-TC2"); |
839,12 → 902,14
CreateRandomPayload(randomPayload.data, seed1, seed2); |
RouteFrame(sourcePortIndex=>0, destinationPortIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Test the configuration of the default route->port 6."); |
PrintS("Result: An unknown address should be routed to port 6."); |
PrintS("Action: Test the configuration of the default route->port 2."); |
PrintS("Result: An unknown address should be routed to port 2."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step2"); |
--------------------------------------------------------------------------- |
852,18 → 917,207
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0a", address=>x"000078", data=>x"00000000"); |
WriteConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0b", address=>x"000078", data=>x"00000006"); |
tid=>x"0b", address=>x"000078", data=>x"00000002"); |
ReadConfig32(portIndex=>0, destinationId=>x"0000", sourceId=>x"0002", hop=>x"00", |
tid=>x"0c", address=>x"000078", data=>x"00000006"); |
tid=>x"0c", address=>x"000078", data=>x"00000002"); |
ExchangeFrames; |
|
-- Send a frame from a port and check if it is correctly routed. |
randomPayload.length := 4; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
RouteFrame(sourcePortIndex=>1, destinationPortIndex=>6, |
RouteFrame(sourcePortIndex=>1, destinationPortIndex=>2, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 3:"); |
PrintS("Action: Test to route a maintenance read request from port 2, "); |
PrintS(" address 0."); |
PrintS("Result: The packet should be routed to port 1 and hop decremented."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step3"); |
--------------------------------------------------------------------------- |
|
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0000", |
size=>"1000", |
tid=>x"be", |
hopCount=>x"01", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
ReceiveFrame(1, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0000", |
size=>"1000", |
tid=>x"be", |
hopCount=>x"00", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 4:"); |
PrintS("Action: Test to route a maintenance write request from port 2, "); |
PrintS(" address 0."); |
PrintS("Result: The packet should be routed to port 1 and hop decremented."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step4"); |
--------------------------------------------------------------------------- |
|
CreateRandomPayload(maintData, seed1, seed2); |
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0001", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"01", |
configOffset=>"000000000000000000000", |
wdptr=>'1', |
dataLength=>8, |
data=>maintData))); |
|
ReceiveFrame(1, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0001", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000000000000000000", |
wdptr=>'1', |
dataLength=>8, |
data=>maintData))); |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 5:"); |
PrintS("Action: Test to route a maintenance read response from port 2, "); |
PrintS(" address 0."); |
PrintS("Result: The packet should be routed to port 1 and hop decremented."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step5"); |
--------------------------------------------------------------------------- |
|
CreateRandomPayload(maintData, seed1, seed2); |
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0010", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"01", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>8, |
data=>maintData))); |
|
ReceiveFrame(1, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000",sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0010", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>8, |
data=>maintData))); |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 6:"); |
PrintS("Action: Test to route a maintenance write response from port 2, "); |
PrintS(" address 0."); |
PrintS("Result: The packet should be routed to port 1 and hop decremented."); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step6"); |
--------------------------------------------------------------------------- |
|
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0011", |
size=>"1000", |
tid=>x"ef", |
hopCount=>x"01", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
ReceiveFrame(1, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0011", |
size=>"1000", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 7:"); |
PrintS("Action: "); |
PrintS("Result: "); |
--------------------------------------------------------------------------- |
PrintR("TG_RioSwitch-TC2-Step7"); |
--------------------------------------------------------------------------- |
|
maintData(0) := x"0123456789abcdef"; |
maintData(1) := x"0011223344550100"; |
maintData(2) := x"1000011800000302"; |
maintData(3) := x"0000000000000000"; |
maintData(4) := x"0000000000000000"; |
maintData(5) := x"0000000000000000"; |
maintData(6) := x"0000000000000800"; |
maintData(7) := x"0000000000000000"; |
|
SendFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"0000", sourceId=>x"dead", |
payload=>RioMaintenance(transaction=>"0001", |
size=>"1100", |
tid=>x"ef", |
hopCount=>x"00", |
configOffset=>"000000000000000000000", |
wdptr=>'1', |
dataLength=>8, |
data=>maintData))); |
|
ReceiveFrame(2, RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
destId=>x"dead", sourceId=>x"0000", |
payload=>RioMaintenance(transaction=>"0011", |
size=>"0000", |
tid=>x"ef", |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioSwitch-TC3"); |
PrintS("Description: Test the routing of normal packets."); |
PrintS("Requirement: XXXXX"); |
879,27 → 1133,19
randomPayload.length := 3; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>0, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
destinationId=>x"0000", sourceId=>x"ffff", payload=>randomPayload); |
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
destinationId=>x"0000", sourceId=>x"ffff", payload=>randomPayload); |
|
-- Frame on port 1 to port 6. |
randomPayload.length := 4; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>1, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
destinationId=>x"ffff", sourceId=>x"0000", payload=>randomPayload); |
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload); |
destinationId=>x"ffff", sourceId=>x"0000", payload=>randomPayload); |
|
wait until frameComplete(1) = '1'; |
frameValid(1) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
|
wait until frameComplete(0) = '1'; |
frameValid(0) <= '0'; |
wait until frameReceived(1) = '1'; |
frameExpected(1) <= '0'; |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
915,57 → 1161,36
-- Frame on port 0 to port 1. |
randomPayload.length := 5; |
CreateRandomPayload(randomPayload.data, seed1, seed2); |
SendFrame(portIndex=>0, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
RouteFrame(sourcePortIndex=>0, destinationPortIndex=>1, |
destinationId=>x"0000", sourceId=>x"ffff", payload=>randomPayload); |
|
-- Frame on port 1 to port 6. |
-- Frame on port 1 to port 2. |
randomPayload1.length := 6; |
CreateRandomPayload(randomPayload1.data, seed1, seed2); |
SendFrame(portIndex=>1, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); |
RouteFrame(sourcePortIndex=>2, destinationPortIndex=>2, |
destinationId=>x"ffff", sourceId=>x"0000", payload=>randomPayload1); |
|
-- Frame on port 2 to port 6. |
-- Frame on port 2 to port 2. |
randomPayload2.length := 7; |
CreateRandomPayload(randomPayload2.data, seed1, seed2); |
SendFrame(portIndex=>2, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); |
RouteFrame(sourcePortIndex=>2, destinationPortIndex=>2, |
destinationId=>x"ffff", sourceId=>x"0000", payload=>randomPayload2); |
|
writeFrameFull <= (others=>'1'); |
wait for 10 us; |
|
ReceiveFrame(portIndex=>1, |
sourceId=>x"ffff", destinationId=>x"0000", payload=>randomPayload); |
wait until frameComplete(0) = '1'; |
frameValid(0) <= '0'; |
wait until frameReceived(1) = '1'; |
frameExpected(1) <= '0'; |
|
writeFrameFull(1) <= '0'; |
wait for 10 us; |
|
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload1); |
wait until frameComplete(1) = '1'; |
frameValid(1) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
|
writeFrameFull(2) <= '0'; |
wait for 10 us; |
|
ReceiveFrame(portIndex=>6, |
sourceId=>x"0000", destinationId=>x"ffff", payload=>randomPayload2); |
wait until frameComplete(2) = '1'; |
frameValid(2) <= '0'; |
wait until frameReceived(6) = '1'; |
frameExpected(6) <= '0'; |
ExchangeFrames; |
|
--------------------------------------------------------------------------- |
-- Test completed. |
--------------------------------------------------------------------------- |
|
wait for 10 us; |
|
assert readContentEmpty = "1111111" |
report "Pending frames exist." severity error; |
|
TestEnd; |
end process; |
|
973,44 → 1198,68
-- Instantiate a process receiving the configuration accesses to the |
-- implementation defined space. |
----------------------------------------------------------------------------- |
process |
begin |
loop |
wait until configStb = '1' and clk'event and clk = '1'; |
assert configStb = configStbExpected report "Unexpected configStb." severity error; |
assert configWe = configWeExpected report "Unexpected configWe." severity error; |
assert configAddr = configAddrExpected report "Unexpected configAddr." severity error; |
if (configWe = '1') then |
assert configDataWrite = configDataWriteExpected report "Unexpected configDataWrite." severity error; |
else |
configDataRead <= configDataReadExpected; |
end if; |
end loop; |
end process; |
|
TestWishbone: TestPortWishbone |
generic map(ADDRESS_WIDTH=>24, SEL_WIDTH=>1, DATA_WIDTH=>32) |
port map( |
clk=>clk, areset_n=>areset_n, |
messageEmpty_o=>messageEmpty, |
messageWrite_i=>messageWrite, |
message_i=>message, |
messageAck_o=>messageAck, |
cyc_i=>configStb, |
stb_i=>configStb, |
we_i=>configWe, |
adr_i=>configAddr, |
sel_i=>"0", |
dat_i=>configDataWrite, |
dat_o=>configDataRead, |
err_o=>open, |
ack_o=>configAck); |
|
----------------------------------------------------------------------------- |
-- Instantiate the test port array. |
----------------------------------------------------------------------------- |
|
inboundEmpty2 <= inboundEmpty(2); |
inboundEmpty1 <= inboundEmpty(1); |
inboundEmpty0 <= inboundEmpty(0); |
inboundWrite <= inboundWrite2 & inboundWrite1 & inboundWrite0; |
inboundMessage <= inboundMessage2 & inboundMessage1 & inboundMessage0; |
inboundAck2 <= inboundAck(2); |
inboundAck1 <= inboundAck(1); |
inboundAck0 <= inboundAck(0); |
outboundEmpty2 <= outboundEmpty(2); |
outboundEmpty1 <= outboundEmpty(1); |
outboundEmpty0 <= outboundEmpty(0); |
outboundWrite <= outboundWrite2 & outboundWrite1 & outboundWrite0; |
outboundMessage <= outboundMessage2 & outboundMessage1 & outboundMessage0; |
outboundAck2 <= outboundAck(2); |
outboundAck1 <= outboundAck(1); |
outboundAck0 <= outboundAck(0); |
TestPortGeneration: for portIndex in 0 to PORTS-1 generate |
TestPortInst: TestPort |
TestPortPacketBufferInst: TestPortPacketBuffer |
generic map(READ_CONTENT_END_DATA_VALID=>false) |
port map( |
clk=>clk, areset_n=>areset_n, |
frameValid_i=>frameValid(portIndex), |
frameWrite_i=>frameWrite(portIndex), |
frameComplete_o=>frameComplete(portIndex), |
frameExpected_i=>frameExpected(portIndex), |
frameRead_i=>frameRead(portIndex), |
frameReceived_o=>frameReceived(portIndex), |
readEmpty_o=>inboundEmpty(portIndex), |
readWrite_i=>inboundWrite(portIndex), |
readMessage_i=>inboundMessage(portIndex), |
readAck_o=>inboundAck(portIndex), |
writeEmpty_o=>outboundEmpty(portIndex), |
writeWrite_i=>outboundWrite(portIndex), |
writeMessage_i=>outboundMessage(portIndex), |
writeAck_o=>outboundAck(portIndex), |
readFrameEmpty_o=>readFrameEmpty(portIndex), |
readFrame_i=>readFrame(portIndex), |
readFrameRestart_i=>readFrameRestart(portIndex), |
readFrameAborted_o=>readFrameAborted(portIndex), |
readFrameRestart_i=>'0', |
readFrameAborted_o=>readFrameAborted(portIndex), |
readWindowEmpty_o=>open, |
readWindowReset_i=>'0', |
readWindowNext_i=>readFrame(portIndex), |
readContentEmpty_o=>readContentEmpty(portIndex), |
readContent_i=>readContent(portIndex), |
readContentEnd_o=>readContentEnd(portIndex), |
readContentData_o=>readContentData(portIndex), |
writeFrameFull_o=>writeFrameFull(portIndex), |
writeFrame_i=>writeFrame(portIndex), |
writeFrameAbort_i=>writeFrameAbort(portIndex), |
writeContent_i=>writeContent(portIndex), |
1023,7 → 1272,7
|
TestSwitch: RioSwitch |
generic map( |
SWITCH_PORTS=>7, |
SWITCH_PORTS=>PORTS, |
DEVICE_IDENTITY=>SWITCH_IDENTITY, |
DEVICE_VENDOR_IDENTITY=>SWITCH_VENDOR_IDENTITY, |
DEVICE_REV=>SWITCH_REV, |
1053,213 → 1302,7
outstandingAckId_i=>outstandingAckIdRead, |
outboundAckId_i=>outboundAckIdRead, |
configStb_o=>configStb, configWe_o=>configWe, configAddr_o=>configAddr, |
configData_o=>configDataWrite, configData_i=>configDataRead); |
configData_o=>configDataWrite, configData_i=>configDataRead, configAck_i=>configAck); |
|
|
end architecture; |
|
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
-- REMARK: Add support for testing partially complete frames, cut-through-routing... |
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; |
/2.0.0-development/rtl/vhdl/RioLogicalPackets.vhd
76,13 → 76,15
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); |
size_o : out std_logic_vector(3 downto 0); |
status_o : out std_logic_vector(3 downto 0); |
tid_o : out std_logic_vector(7 downto 0); |
hop_o : out std_logic_vector(7 downto 0); |
offset_o : out std_logic_vector(20 downto 0); |
wdptr_o : out std_logic; |
payloadLength_o : out std_logic_vector(3 downto 0); |
payloadIndex_i : in std_logic_vector(3 downto 0); |
payload_o : out std_logic_vector(31 downto 0); |
payloadLength_o : out std_logic_vector(2 downto 0); |
payloadIndex_i : in std_logic_vector(2 downto 0); |
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
inboundCyc_i : in std_logic; |
103,25 → 105,26
|
signal wdptr : std_logic; |
signal size : std_logic_vector(3 downto 0); |
signal words : natural range 0 to 32; |
|
signal inboundAck : std_logic; |
signal maintReadComplete : std_logic; |
signal maintWriteComplete : std_logic; |
signal readRequestComplete : std_logic; |
signal writeRequestComplete : std_logic; |
signal readResponseComplete : std_logic; |
signal writeResponseComplete : std_logic; |
|
signal packetIndex : natural range 0 to 33; |
signal packetData : std_logic_vector(31 downto 0); |
signal packetIndex : natural range 0 to 21; |
signal packetData : std_logic_vector(47 downto 0); |
|
signal memoryWrite : std_logic; |
signal memoryAddress : std_logic_vector(3 downto 0); |
signal memoryDataIn : std_logic_vector(31 downto 0); |
signal memoryAddress : std_logic_vector(2 downto 0); |
signal memoryDataIn : std_logic_vector(63 downto 0); |
|
begin |
|
readRequestReady_o <= maintReadComplete when (state = READY) else '0'; |
writeRequestReady_o <= maintWriteComplete when (state = READY) else '0'; |
readResponseReady_o <= '0'; |
writeResponseReady_o <= '0'; |
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'; |
|
inboundAck_o <= inboundAck; |
130,8 → 133,10
if (areset_n = '0') then |
inboundAck <= '0'; |
|
maintReadComplete <= '0'; |
maintWriteComplete <= '0'; |
readRequestComplete <= '0'; |
writeRequestComplete <= '0'; |
readResponseComplete <= '0'; |
writeResponseComplete <= '0'; |
|
vc_o <= '0'; |
crf_o <= '0'; |
139,6 → 144,7
tt_o <= "00"; |
dstid_o <= (others=>'0'); |
srcid_o <= (others=>'0'); |
status_o <= (others=>'0'); |
tid_o <= (others=>'0'); |
hop_o <= (others=>'0'); |
offset_o <= (others=>'0'); |
192,10 → 198,11
offset_o(12 downto 0) <= inboundDat_i(31 downto 19); |
wdptr <= inboundDat_i(18); |
packetIndex <= packetIndex + 1; |
maintReadComplete <= '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 |
229,29 → 236,23
-- 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(31 downto 16) <= inboundDat_i(15 downto 0); |
packetData(47 downto 32) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 => |
-- double-word(47:16) |
packetData(31 downto 16) <= inboundDat_i(15 downto 0); |
packetData(31 downto 0) <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
|
if (not ((size = "1000") and (wdptr = '1'))) then |
memoryWrite <= '1'; |
memoryDataIn <= packetData(31 downto 16) & inboundDat_i(31 downto 16); |
end if; |
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => |
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 => |
-- double-word(15:0) & double-word(63:48) |
packetData(31 downto 16) <= inboundDat_i(15 downto 0); |
packetData(47 downto 32) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
|
memoryWrite <= '1'; |
memoryDataIn <= packetData(31 downto 16) & inboundDat_i(31 downto 16); |
-- REMARK: Dont set complete before the packet is ready... |
maintWriteComplete <= '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 |
258,10 → 259,85
------------------------------------------------------------- |
-- 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. |
270,8 → 346,7
------------------------------------------------------------- |
-- Unsupported maintenance packet. |
------------------------------------------------------------- |
-- REMARK: Cannot handle these, dont answer. Or answer and |
-- discard? |
-- Cannot handle these, dont answer. |
end if; |
end if; |
else |
283,11 → 358,13
inboundAck <= '0'; |
end if; |
else |
if (maintReadComplete = '1') or (maintWriteComplete = '1') then |
if ((readRequestComplete = '1') or (writeRequestComplete = '1') or |
(readResponseComplete = '1') or (writeResponseComplete = '1')) then |
state <= READY; |
else |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
end if; |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
end if; |
|
when READY => |
296,8 → 373,13
-- processed. |
--------------------------------------------------------------------- |
if (done_i = '1') then |
maintReadComplete <= '0'; |
maintWriteComplete <= '0'; |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
|
readRequestComplete <= '0'; |
writeRequestComplete <= '0'; |
readResponseComplete <= '0'; |
writeResponseComplete <= '0'; |
state <= RECEIVE_PACKET; |
end if; |
|
317,49 → 399,22
process(clk, areset_n) |
begin |
if (areset_n = '0') then |
size_o <= (others=>'0'); |
wdptr_o <= '0'; |
payloadLength_o <= (others=>'0'); |
wdptr_o <= '0'; |
elsif (clk'event and clk = '1') then |
if (maintReadComplete = '1') or (maintWriteComplete = '1') then |
if (wdptr = '0') then |
case size is |
when "1000" => |
-- Read 1 word. |
payloadLength_o <= "0000"; |
wdptr_o <= '0'; |
when "1011" => |
-- Read 2 words. |
payloadLength_o <= "0001"; |
wdptr_o <= '0'; |
when "1100" => |
-- Read 8 words. |
payloadLength_o <= "0111"; |
wdptr_o <= '0'; |
when others => |
-- REMARK: Not allowed for a maintenance packet. |
payloadLength_o <= "0000"; |
wdptr_o <= '0'; |
end case; |
else |
case size is |
when "1000" => |
-- Read 1 word. |
payloadLength_o <= "0000"; |
wdptr_o <= '1'; |
when "1011" => |
-- Read 4 words. |
payloadLength_o <= "0011"; |
wdptr_o <= '0'; |
when "1100" => |
-- Read 16 words. |
payloadLength_o <= "1111"; |
wdptr_o <= '0'; |
when others => |
-- REMARK: Not allowed for a maintenance packet. |
payloadLength_o <= "0000"; |
wdptr_o <= '0'; |
end case; |
end if; |
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'); |
end if; |
end if; |
end process; |
368,7 → 423,7
-- Payload content memory. |
----------------------------------------------------------------------------- |
PayloadMemory: MemorySimpleDualPort |
generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) |
generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64) |
port map(clkA_i=>clk, |
enableA_i=>memoryWrite, |
addressA_i=>memoryAddress, |
409,14 → 464,15
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); |
size_i : in std_logic_vector(3 downto 0); |
status_i : in std_logic_vector(3 downto 0); |
tid_i : in std_logic_vector(7 downto 0); |
hop_i : in std_logic_vector(7 downto 0); |
offset_i : in std_logic_vector(20 downto 0); |
wdptr_i : in std_logic; |
offset_i : in std_logic_vector(20 downto 0); |
payloadLength_i : in std_logic_vector(3 downto 0); |
payloadIndex_o : out std_logic_vector(3 downto 0); |
payload_i : in std_logic_vector(31 downto 0); |
payloadLength_i : in std_logic_vector(2 downto 0); |
payloadIndex_o : out std_logic_vector(2 downto 0); |
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
outboundCyc_o : out std_logic; |
431,14 → 487,15
------------------------------------------------------------------------------- |
architecture MaintenanceOutbound of MaintenanceOutbound is |
type StateType is (WAIT_PACKET, |
READ_REQUEST, WRITE_REQUEST, |
READ_RESPONSE, WRITE_RESPONSE, |
WAIT_COMPLETE, RESPONSE_DONE); |
signal state : StateType; |
|
signal packetIndex : natural range 0 to 33; |
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(3 downto 0); |
signal payloadIndex : std_logic_vector(2 downto 0); |
|
begin |
|
467,12 → 524,24
------------------------------------------------------------------- |
-- |
------------------------------------------------------------------- |
if (readResponseReady_i = '1') then |
payloadIndex <= (others=>'0'); |
if (readRequestReady_i = '1') then |
outboundCyc_o <= '1'; |
outboundStb_o <= '1'; |
outboundDat_o <= header; |
packetIndex <= 1; |
payloadIndex <= (others=>'0'); |
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'; |
482,6 → 551,75
state <= WRITE_RESPONSE; |
end if; |
|
when READ_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 & 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); |
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); |
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); |
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; |
|
if (payloadIndex = payloadLength_i) then |
state <= WAIT_COMPLETE; |
end if; |
when others => |
-- double-wordN(15:0) & double-wordN(63:48) |
outboundDat_o <= payload & x"0000"; |
state <= WAIT_COMPLETE; |
end case; |
end if; |
|
when READ_RESPONSE => |
--------------------------------------------------------------------- |
-- |
489,11 → 627,11
if (outboundAck_i = '1') then |
case (packetIndex) is |
when 1 => |
-- destination |
-- dstid |
outboundDat_o <= dstid_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- source |
-- srcid |
outboundDat_o <= srcid_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
502,57 → 640,26
packetIndex <= packetIndex + 1; |
when 4 => |
-- reserved(15:0) & double-wordN(63:48) |
if (payloadLength_i = "0000") and (wdptr_i = '0') then |
outboundDat_o <= x"0000" & payload_i(31 downto 16); |
payload <= payload_i(15 downto 0); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then |
outboundDat_o <= x"0000" & x"0000"; |
else |
outboundDat_o <= x"0000" & payload_i(31 downto 16); |
payload <= payload_i(15 downto 0); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
end if; |
outboundDat_o <= x"0000" & payload_i(63 downto 48); |
packetIndex <= packetIndex + 1; |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 => |
-- double-wordN(47:16) |
if (payloadLength_i = "0000") and (wdptr_i = '0') then |
outboundDat_o <= payload & x"0000"; |
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then |
outboundDat_o <= x"0000" & payload_i(31 downto 16); |
payload <= payload_i(15 downto 0); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
else |
outboundDat_o <= payload & payload_i(31 downto 16); |
payload <= payload_i(15 downto 0); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
end if; |
outboundDat_o <= payload_i(47 downto 16); |
payload <= payload_i(15 downto 0); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
packetIndex <= packetIndex + 1; |
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => |
when 6 | 8 | 10 | 12 | 14 | 16 | 18 => |
-- double-wordN(15:0) & double-wordN(63:48) |
if (payloadLength_i = "0000") and (wdptr_i = '0') then |
outboundDat_o <= x"0000" & x"0000"; |
elsif (payloadLength_i = "0000") and (wdptr_i = '1') then |
outboundDat_o <= payload & x"0000"; |
else |
if (payloadIndex /= payloadLength_i) then |
outboundDat_o <= payload & payload_i(31 downto 16); |
payload <= payload_i(15 downto 0); |
else |
outboundDat_o <= payload & x"0000"; |
payload <= payload_i(15 downto 0); |
end if; |
end if; |
|
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
if (payloadIndex(3 downto 1) = payloadLength_i(3 downto 1)) then |
outboundDat_o <= payload & payload_i(63 downto 48); |
packetIndex <= packetIndex + 1; |
|
if (payloadIndex = payloadLength_i) then |
state <= WAIT_COMPLETE; |
else |
packetIndex <= packetIndex + 1; |
end if; |
when others => |
-- Unallowed response length. |
-- Dont do anything. |
-- double-wordN(15:0) & double-wordN(63:48) |
outboundDat_o <= payload & x"0000"; |
state <= WAIT_COMPLETE; |
end case; |
end if; |
|
563,11 → 670,11
if (outboundAck_i = '1') then |
case (packetIndex) is |
when 1 => |
-- destination |
-- dstid |
outboundDat_o <= dstid_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- source |
-- srcid |
outboundDat_o <= srcid_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
596,7 → 703,8
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (readResponseReady_i = '0') and (writeResponseReady_i = '0') then |
if ((readRequestReady_i = '0') and (writeRequestReady_i = '0') and |
(readResponseReady_i = '0') and (writeResponseReady_i = '0')) then |
state <= WAIT_PACKET; |
done_o <= '0'; |
else |
/2.0.0-development/rtl/vhdl/RioWbBridge.vhd
10,10 → 10,9
-- NWRITE, NWRITER and NREAD are currently supported. |
-- |
-- To Do: |
-- - Move packet handlers to RioLogicalPackets. |
-- - Move component declarations to riocommon. |
-- - Update the Maintenance handler to the new interface. It currently does not |
-- compile. |
-- - 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 |
21,8 → 20,6
-- - Add support for the lock_o to be sure to transfer all the packet |
-- content atomically? |
-- - Add support for EXTENDED_ADDRESS. |
-- - Add support for addressing to implementation defined config space by |
-- adding interface to top entity. |
-- - Use the baseDeviceId when sending packets? Currently, all responses |
-- are sent with destination<->source exchanged so the baseDeviceId is not |
-- needed. |
275,21 → 272,22
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(3 downto 0); |
signal payloadInbound : std_logic_vector(31 downto 0); |
signal payloadLengthInbound : std_logic_vector(2 downto 0); |
signal payloadInbound : std_logic_vector(63 downto 0); |
|
signal readResponseMaint : std_logic; |
signal writeResponseMaint : std_logic; |
signal wdptrMaint : std_logic; |
signal payloadLengthMaint : std_logic_vector(3 downto 0); |
signal payloadIndexMaint : std_logic_vector(3 downto 0); |
signal payloadMaint : std_logic_vector(31 downto 0); |
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(3 downto 0); |
signal payloadIndexOutbound : std_logic_vector(2 downto 0); |
signal doneOutbound : std_logic; |
|
signal configStb : std_logic; |
571,7 → 569,9
prio_o=>prioInbound, |
tt_o=>ttInbound, |
dstid_o=>dstIdInbound, |
srcid_o=>srcIdInbound, |
srcid_o=>srcIdInbound, |
size_o=>sizeInbound, |
status_o=>open, |
tid_o=>tidInbound, |
hop_o=>open, |
offset_o=>offsetInbound, |
600,11 → 600,12
tt_i=>ttInbound, |
dstid_i=>srcIdInbound, |
srcid_i=>dstIdInbound, |
status_i=>"0000", |
size_i=>(others=>'0'), |
status_i=>statusMaint, |
tid_i=>tidInbound, |
hop_i=>x"ff", |
offset_i=>(others=>'0'), |
wdptr_i=>wdptrMaint, |
wdptr_i=>'0', |
payloadLength_i=>payloadLengthMaint, |
payloadIndex_o=>payloadIndexOutbound, |
payload_i=>payloadMaint, |
618,7 → 619,8
port map( |
clk=>clk, areset_n=>areset_n, enable=>enable, |
readRequestReady_i=>readRequestInbound, |
writeRequestReady_i=>writeRequestInbound, |
writeRequestReady_i=>writeRequestInbound, |
size_i=>sizeInbound, |
offset_i=>offsetInbound, |
wdptr_i=>wdptrInbound, |
payloadLength_i=>payloadLengthInbound, |
627,7 → 629,7
done_o=>doneMaint, |
readResponseReady_o=>readResponseMaint, |
writeResponseReady_o=>writeResponseMaint, |
wdptr_o=>wdptrMaint, |
status_o=>statusMaint, |
payloadLength_o=>payloadLengthMaint, |
payloadIndex_i=>payloadIndexOutbound, |
payload_o=>payloadMaint, |
1151,22 → 1153,6
-- |
------------------------------------------------------------------------------- |
architecture WriteClassInbound of WriteClassInbound is |
component MemorySimpleDualPort |
generic( |
ADDRESS_WIDTH : natural := 1; |
DATA_WIDTH : natural := 1); |
port( |
clkA_i : in std_logic; |
enableA_i : in std_logic; |
addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); |
|
clkB_i : in std_logic; |
enableB_i : in std_logic; |
addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); |
end component; |
|
type StateType is (RECEIVE_PACKET, READY); |
signal state : StateType; |
|
1482,22 → 1468,6
-- |
------------------------------------------------------------------------------- |
architecture ResponseClassOutbound of ResponseClassOutbound is |
component MemorySimpleDualPort |
generic( |
ADDRESS_WIDTH : natural := 1; |
DATA_WIDTH : natural := 1); |
port( |
clkA_i : in std_logic; |
enableA_i : in std_logic; |
addressA_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
dataA_i : in std_logic_vector(DATA_WIDTH-1 downto 0); |
|
clkB_i : in std_logic; |
enableB_i : in std_logic; |
addressB_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0); |
dataB_o : out std_logic_vector(DATA_WIDTH-1 downto 0)); |
end component; |
|
signal header : std_logic_vector(31 downto 0); |
|
type StateType is (WAIT_PACKET, SEND_RESPONSE, |
/2.0.0-development/rtl/vhdl/RioCommon.vhd
140,19 → 140,20
|
readRequestReady_i : in std_logic; |
writeRequestReady_i : in std_logic; |
size_i : in std_logic_vector(3 downto 0); |
offset_i : in std_logic_vector(20 downto 0); |
wdptr_i : in std_logic; |
payloadLength_i : in std_logic_vector(3 downto 0); |
payloadIndex_o : out std_logic_vector(3 downto 0); |
payload_i : in std_logic_vector(31 downto 0); |
payloadLength_i : in std_logic_vector(2 downto 0); |
payloadIndex_o : out std_logic_vector(2 downto 0); |
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
readResponseReady_o : out std_logic; |
writeResponseReady_o : out std_logic; |
wdptr_o : out std_logic; |
payloadLength_o : out std_logic_vector(3 downto 0); |
payloadIndex_i : in std_logic_vector(3 downto 0); |
payload_o : out std_logic_vector(31 downto 0); |
status_o : out std_logic_vector(3 downto 0); |
payloadLength_o : out std_logic_vector(2 downto 0); |
payloadIndex_i : in std_logic_vector(2 downto 0); |
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
configStb_o : out std_logic; |
180,13 → 181,15
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); |
size_o : out std_logic_vector(3 downto 0); |
status_o : out std_logic_vector(3 downto 0); |
tid_o : out std_logic_vector(7 downto 0); |
hop_o : out std_logic_vector(7 downto 0); |
offset_o : out std_logic_vector(20 downto 0); |
wdptr_o : out std_logic; |
payloadLength_o : out std_logic_vector(3 downto 0); |
payloadIndex_i : in std_logic_vector(3 downto 0); |
payload_o : out std_logic_vector(31 downto 0); |
payloadLength_o : out std_logic_vector(2 downto 0); |
payloadIndex_i : in std_logic_vector(2 downto 0); |
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
inboundCyc_i : in std_logic; |
213,14 → 216,15
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); |
size_i : in std_logic_vector(3 downto 0); |
status_i : in std_logic_vector(3 downto 0); |
tid_i : in std_logic_vector(7 downto 0); |
hop_i : in std_logic_vector(7 downto 0); |
offset_i : in std_logic_vector(20 downto 0); |
wdptr_i : in std_logic; |
payloadLength_i : in std_logic_vector(3 downto 0); |
payloadIndex_o : out std_logic_vector(3 downto 0); |
payload_i : in std_logic_vector(31 downto 0); |
payloadLength_i : in std_logic_vector(2 downto 0); |
payloadIndex_o : out std_logic_vector(2 downto 0); |
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
outboundCyc_o : out std_logic; |
401,11 → 405,11
-- Create a randomly initialized data array. |
--------------------------------------------------------------------------- |
procedure CreateRandomPayload( |
variable payload : out HalfwordArray(0 to 132); |
variable payload : out HalfwordArray; |
variable seed1 : inout positive; |
variable seed2 : inout positive); |
procedure CreateRandomPayload( |
variable payload : out DoublewordArray(0 to 31); |
variable payload : out DoublewordArray; |
variable seed1 : inout positive; |
variable seed2 : inout positive); |
|
671,7 → 675,7
-- Create a randomly initialized data array. |
--------------------------------------------------------------------------- |
procedure CreateRandomPayload( |
variable payload : out HalfwordArray(0 to 132); |
variable payload : out HalfwordArray; |
variable seed1 : inout positive; |
variable seed2 : inout positive) is |
variable rand: real; |
689,7 → 693,7
end procedure; |
|
procedure CreateRandomPayload( |
variable payload : out DoublewordArray(0 to 31); |
variable payload : out DoublewordArray; |
variable seed1 : inout positive; |
variable seed2 : inout positive) is |
variable rand: real; |
/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd
1,242 → 1,402
------------------------------------------------------------------------------- |
-- |
-- RapidIO IP Library Core |
-- |
-- This file is part of the RapidIO IP library project |
-- http://www.opencores.org/cores/rio/ |
-- |
-- Description |
-- Contains a platform to build endpoints on. |
-- |
-- To Do: |
-- - |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2013 Authors and OPENCORES.ORG |
-- |
-- This source file may be used and distributed without |
-- restriction provided that this copyright statement is not |
-- removed from the file and that any derivative work contains |
-- the original copyright notice and the associated disclaimer. |
-- |
-- This source file is free software; you can redistribute it |
-- and/or modify it under the terms of the GNU Lesser General |
-- Public License as published by the Free Software Foundation; |
-- either version 2.1 of the License, or (at your option) any |
-- later version. |
-- |
-- This source is distributed in the hope that it will be |
-- useful, but WITHOUT ANY WARRANTY; without even the implied |
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
-- PURPOSE. See the GNU Lesser General Public License for more |
-- details. |
-- |
-- You should have received a copy of the GNU Lesser General |
-- Public License along with this source; if not, download it |
-- from http://www.opencores.org/lgpl.shtml |
-- |
------------------------------------------------------------------------------- |
|
------------------------------------------------------------------------------- |
-- RioLogicalMaintenance |
-- This logical layer module handles ingress maintenance requests and converts |
-- them into accesses on a Wishbone similar bus accessing the configuration |
-- space. |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for RioLogicalMaintenance. |
------------------------------------------------------------------------------- |
entity RioLogicalMaintenance is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
enable : in std_logic; |
|
readRequestReady_i : in std_logic; |
writeRequestReady_i : in std_logic; |
offset_i : in std_logic_vector(20 downto 0); |
wdptr_i : in std_logic; |
payloadLength_i : in std_logic_vector(3 downto 0); |
payloadIndex_o : out std_logic_vector(3 downto 0); |
payload_i : in std_logic_vector(31 downto 0); |
done_o : out std_logic; |
|
readResponseReady_o : out std_logic; |
writeResponseReady_o : out std_logic; |
wdptr_o : out std_logic; |
payloadLength_o : out std_logic_vector(3 downto 0); |
payloadIndex_i : in std_logic_vector(3 downto 0); |
payload_o : out std_logic_vector(31 downto 0); |
done_i : in std_logic; |
|
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 entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture RioLogicalMaintenance of RioLogicalMaintenance is |
|
type StateType is (IDLE, |
CONFIG_READ, CONFIG_READ_RESPONSE, |
CONFIG_WRITE, CONFIG_WRITE_RESPONSE); |
signal state : StateType; |
|
signal payloadWrite : std_logic; |
signal payloadIndex : std_logic_vector(3 downto 0); |
|
signal configAdr : std_logic_vector(21 downto 0); |
signal configDat : std_logic_vector(31 downto 0); |
|
begin |
|
wdptr_o <= wdptr_i; |
|
configAdr_o <= configAdr; |
configDat_o <= configDat; |
|
payloadLength_o <= payloadLength_i; |
payloadIndex_o <= payloadIndex; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Maintenance: process(clk, areset_n) |
begin |
if (areset_n = '0') then |
state <= IDLE; |
|
configStb_o <= '0'; |
configWe_o <= '0'; |
configAdr <= (others=>'0'); |
configDat <= (others=>'0'); |
|
readResponseReady_o <= '0'; |
writeResponseReady_o <= '0'; |
|
done_o <= '0'; |
|
payloadWrite <= '0'; |
payloadIndex <= (others=>'0'); |
elsif (clk'event and clk = '1') then |
payloadWrite <= '0'; |
|
if (payloadWrite = '1') then |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
end if; |
|
case state is |
when IDLE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
payloadIndex <= (others=>'0'); |
if (readRequestReady_i = '1') then |
configStb_o <= '1'; |
configWe_o <= '0'; |
configAdr <= offset_i & wdptr_i; |
state <= CONFIG_READ; |
elsif (writeRequestReady_i = '1') then |
configStb_o <= '1'; |
configWe_o <= '1'; |
configAdr <= offset_i & wdptr_i; |
configDat <= payload_i; |
state <= CONFIG_WRITE; |
end if; |
|
when CONFIG_READ => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (configAck_i = '1') then |
payloadWrite <= '1'; |
|
if (payloadIndex /= payloadLength_i) then |
configAdr <= std_logic_vector(unsigned(configAdr) + 1); |
else |
done_o <= '1'; |
configStb_o <= '0'; |
state <= CONFIG_READ_RESPONSE; |
end if; |
end if; |
|
when CONFIG_READ_RESPONSE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (done_i = '1') then |
done_o <= '0'; |
readResponseReady_o <= '0'; |
state <= IDLE; |
else |
readResponseReady_o <= '1'; |
end if; |
|
when CONFIG_WRITE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (configAck_i = '1') then |
payloadWrite <= '1'; |
|
if (payloadIndex /= payloadLength_i) then |
configAdr <= std_logic_vector(unsigned(configAdr) + 1); |
configDat <= payload_i; |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
else |
done_o <= '1'; |
configStb_o <= '0'; |
state <= CONFIG_WRITE_RESPONSE; |
end if; |
end if; |
|
when CONFIG_WRITE_RESPONSE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (done_i = '1') then |
done_o <= '0'; |
writeResponseReady_o <= '0'; |
state <= IDLE; |
else |
writeResponseReady_o <= '1'; |
end if; |
|
when others => |
|
end case; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Payload content memory. |
----------------------------------------------------------------------------- |
|
PayloadMemory: MemorySimpleDualPort |
generic map(ADDRESS_WIDTH=>4, DATA_WIDTH=>32) |
port map(clkA_i=>clk, |
enableA_i=>payloadWrite, |
addressA_i=>payloadIndex, |
dataA_i=>configDat_i, |
clkB_i=>clk, |
enableB_i=>'1', |
addressB_i=>payloadIndex_i, |
dataB_o=>payload_o); |
|
end architecture; |
------------------------------------------------------------------------------- |
-- |
-- RapidIO IP Library Core |
-- |
-- This file is part of the RapidIO IP library project |
-- http://www.opencores.org/cores/rio/ |
-- |
-- Description |
-- Contains a platform to build endpoints on. |
-- |
-- To Do: |
-- - Clean up the code for reading. Works but messy. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
-- |
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2013 Authors and OPENCORES.ORG |
-- |
-- This source file may be used and distributed without |
-- restriction provided that this copyright statement is not |
-- removed from the file and that any derivative work contains |
-- the original copyright notice and the associated disclaimer. |
-- |
-- This source file is free software; you can redistribute it |
-- and/or modify it under the terms of the GNU Lesser General |
-- Public License as published by the Free Software Foundation; |
-- either version 2.1 of the License, or (at your option) any |
-- later version. |
-- |
-- This source is distributed in the hope that it will be |
-- useful, but WITHOUT ANY WARRANTY; without even the implied |
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
-- PURPOSE. See the GNU Lesser General Public License for more |
-- details. |
-- |
-- You should have received a copy of the GNU Lesser General |
-- Public License along with this source; if not, download it |
-- from http://www.opencores.org/lgpl.shtml |
-- |
------------------------------------------------------------------------------- |
|
------------------------------------------------------------------------------- |
-- RioLogicalMaintenance |
-- This logical layer module handles ingress maintenance requests and converts |
-- them into accesses on a Wishbone similar bus accessing the configuration |
-- space. |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for RioLogicalMaintenance. |
------------------------------------------------------------------------------- |
entity RioLogicalMaintenance is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
enable : in std_logic; |
|
readRequestReady_i : in std_logic; |
writeRequestReady_i : in std_logic; |
size_i : in std_logic_vector(3 downto 0); |
offset_i : in std_logic_vector(20 downto 0); |
wdptr_i : in std_logic; |
payloadLength_i : in std_logic_vector(2 downto 0); |
payloadIndex_o : out std_logic_vector(2 downto 0); |
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
readResponseReady_o : out std_logic; |
writeResponseReady_o : out std_logic; |
status_o : out std_logic_vector(3 downto 0); |
payloadLength_o : out std_logic_vector(2 downto 0); |
payloadIndex_i : in std_logic_vector(2 downto 0); |
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
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 entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture RioLogicalMaintenance of RioLogicalMaintenance is |
|
type StateType is (IDLE, |
CONFIG_READ_START, CONFIG_READ, CONFIG_READ_NEXT, CONFIG_READ_RESPONSE, |
CONFIG_WRITE_START, CONFIG_WRITE, CONFIG_WRITE_NEXT, CONFIG_WRITE_RESPONSE, |
WAIT_REQUEST); |
signal state : StateType; |
|
signal payloadLength : std_logic_vector(3 downto 0); |
signal payloadIndex : std_logic_vector(3 downto 0); |
|
signal payloadWrite : std_logic; |
signal payloadAddress : std_logic_vector(2 downto 0); |
signal payload : std_logic_vector(63 downto 0); |
|
signal configAdr : std_logic_vector(21 downto 0); |
signal configDat : std_logic_vector(31 downto 0); |
|
begin |
|
configAdr_o <= configAdr; |
configDat_o <= configDat; |
|
payloadLength_o <= payloadLength(3 downto 1); |
payloadIndex_o <= payloadIndex(3 downto 1); |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
Maintenance: process(clk, areset_n) |
begin |
if (areset_n = '0') then |
state <= IDLE; |
|
readResponseReady_o <= '0'; |
writeResponseReady_o <= '0'; |
done_o <= '0'; |
|
configStb_o <= '0'; |
configWe_o <= '0'; |
configAdr <= (others=>'0'); |
configDat <= (others=>'0'); |
|
payloadWrite <= '0'; |
payloadIndex <= (others=>'0'); |
payload <= (others=>'0'); |
elsif (clk'event and clk = '1') then |
payloadWrite <= '0'; |
|
case state is |
when IDLE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
done_o <= '0'; |
if (readRequestReady_i = '1') then |
state <= CONFIG_READ_START; |
elsif (writeRequestReady_i = '1') then |
state <= CONFIG_WRITE_START; |
end if; |
|
when CONFIG_READ_START => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
configStb_o <= '1'; |
configWe_o <= '0'; |
if (size_i = "1000") then |
configAdr <= offset_i & wdptr_i; |
else |
configAdr <= offset_i & '0'; |
end if; |
payloadIndex <= "0000"; |
payload <= (others=>'0'); |
state <= CONFIG_READ; |
|
when CONFIG_READ => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (configAck_i = '1') then |
configStb_o <= '0'; |
configAdr <= std_logic_vector(unsigned(configAdr) + 1); |
state <= CONFIG_READ_NEXT; |
end if; |
|
if (size_i = "1000") and (wdptr_i = '0') then |
payload(63 downto 32) <= configDat_i; |
elsif (size_i = "1000") and (wdptr_i = '1') then |
payload(31 downto 0) <= configDat_i; |
else |
if (payloadIndex(0) = '0') then |
payload(63 downto 32) <= configDat_i; |
else |
payload(31 downto 0) <= configDat_i; |
end if; |
end if; |
|
when CONFIG_READ_NEXT => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (size_i = "1000") and (wdptr_i = '0') then |
-- 1 word. |
status_o <= "0000"; |
payloadLength <= "0010"; |
payloadWrite <= '1'; |
state <= CONFIG_READ_RESPONSE; |
elsif (size_i = "1000") and (wdptr_i = '1') then |
-- 1 word. |
status_o <= "0000"; |
payloadLength <= "0010"; |
payloadWrite <= '1'; |
state <= CONFIG_READ_RESPONSE; |
elsif (size_i = "1011") and (wdptr_i = '0') then |
-- 2 words. |
status_o <= "0000"; |
payloadLength <= "0010"; |
payloadWrite <= payloadIndex(0); |
if (payloadIndex = "0001") then |
state <= CONFIG_READ_RESPONSE; |
else |
configStb_o <= '1'; |
state <= CONFIG_READ; |
end if; |
elsif (size_i = "1011") and (wdptr_i = '1') then |
-- 4 words. |
status_o <= "0000"; |
payloadLength <= "0100"; |
payloadWrite <= payloadIndex(0); |
if (payloadIndex = "0011") then |
state <= CONFIG_READ_RESPONSE; |
else |
configStb_o <= '1'; |
state <= CONFIG_READ; |
end if; |
elsif (size_i = "1100") and (wdptr_i = '0') then |
-- 8 words. |
status_o <= "0000"; |
payloadLength <= "1000"; |
payloadWrite <= payloadIndex(0); |
if (payloadIndex = "0111") then |
state <= CONFIG_READ_RESPONSE; |
else |
configStb_o <= '1'; |
state <= CONFIG_READ; |
end if; |
elsif (size_i = "1100") and (wdptr_i = '1') then |
-- 16 words. |
status_o <= "0000"; |
payloadLength <= "0000"; |
payloadWrite <= payloadIndex(0); |
if (payloadIndex = "1111") then |
state <= CONFIG_READ_RESPONSE; |
else |
configStb_o <= '1'; |
state <= CONFIG_READ; |
end if; |
else |
-- Unallowed packet. |
-- Send write-response with status indicating error. |
status_o <= "0111"; |
state <= CONFIG_READ_RESPONSE; |
end if; |
|
payloadAddress <= payloadIndex(3 downto 1); |
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
|
when CONFIG_READ_RESPONSE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (done_i = '1') then |
readResponseReady_o <= '0'; |
state <= WAIT_REQUEST; |
else |
readResponseReady_o <= '1'; |
end if; |
|
when CONFIG_WRITE_START => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
configWe_o <= '1'; |
if (size_i = "1000") then |
configAdr <= offset_i & wdptr_i; |
else |
configAdr <= offset_i & '0'; |
end if; |
if (size_i = "1000") and (wdptr_i = '0') then |
-- 1 word. |
configStb_o <= '1'; |
configDat <= payload_i(63 downto 32); |
payloadLength <= "0001"; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
elsif (size_i = "1000") and (wdptr_i = '1') then |
-- 1 word. |
configStb_o <= '1'; |
configDat <= payload_i(31 downto 0); |
payloadLength <= "0001"; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
elsif (size_i = "1011") and (wdptr_i = '0') then |
-- 2 words. |
configStb_o <= '1'; |
configDat <= payload_i(63 downto 32); |
payloadLength <= "0010"; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
elsif (size_i = "1011") and (wdptr_i = '1') then |
-- maximum 4 words. |
configStb_o <= '1'; |
configDat <= payload_i(63 downto 32); |
payloadLength <= payloadLength_i & '0'; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
elsif (size_i = "1100") and (wdptr_i = '0') then |
-- maximum 8 words. |
configStb_o <= '1'; |
configDat <= payload_i(63 downto 32); |
payloadLength <= payloadLength_i & '0'; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
elsif (size_i = "1100") and (wdptr_i = '1') then |
-- maximum 16 words. |
configStb_o <= '1'; |
configDat <= payload_i(63 downto 32); |
payloadLength <= payloadLength_i & '0'; |
status_o <= "0000"; |
state <= CONFIG_WRITE; |
else |
-- Unallowed packet. |
-- Send write-response with status indicating error. |
status_o <= "0111"; |
state <= CONFIG_WRITE_RESPONSE; |
end if; |
payloadIndex <= "0001"; |
|
when CONFIG_WRITE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (configAck_i = '1') then |
configStb_o <= '0'; |
configAdr <= std_logic_vector(unsigned(configAdr) + 1); |
state <= CONFIG_WRITE_NEXT; |
end if; |
|
when CONFIG_WRITE_NEXT => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (payloadIndex(0) = '0') then |
configDat <= payload_i(63 downto 32); |
else |
configDat <= payload_i(31 downto 0); |
end if; |
|
payloadIndex <= std_logic_vector(unsigned(payloadIndex) + 1); |
if (payloadIndex /= payloadLength) then |
configStb_o <= '1'; |
state <= CONFIG_WRITE; |
else |
state <= CONFIG_WRITE_RESPONSE; |
end if; |
|
when CONFIG_WRITE_RESPONSE => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (done_i = '1') then |
writeResponseReady_o <= '0'; |
state <= WAIT_REQUEST; |
else |
writeResponseReady_o <= '1'; |
end if; |
|
when WAIT_REQUEST => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
done_o <= '1'; |
if (readRequestReady_i = '0') and (writeRequestReady_i = '0') then |
state <= IDLE; |
end if; |
when others => |
|
end case; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Payload content memory. |
----------------------------------------------------------------------------- |
|
PayloadMemory: MemorySimpleDualPort |
generic map(ADDRESS_WIDTH=>3, DATA_WIDTH=>64) |
port map(clkA_i=>clk, |
enableA_i=>payloadWrite, |
addressA_i=>payloadAddress, |
dataA_i=>payload, |
clkB_i=>clk, |
enableB_i=>'1', |
addressB_i=>payloadIndex_i, |
dataB_o=>payload_o); |
|
end architecture; |
/2.0.0-development/rtl/vhdl/RioSwitch.vhd
10,10 → 10,6
-- entity RioSwitch. |
-- |
-- To Do: |
-- - Add configAck to external interface. |
-- - Complete forwarding of maintenance packets. |
-- - Remove all common component-declarations and move them to RioCommon. |
-- - Add support for longer maintenance packets. |
-- - Add support for portWrite maintenance packets. |
-- - Add a real crossbar as interconnect. |
-- - Change the internal addressing to one-hot. |
56,6 → 52,10
-- from http://www.opencores.org/lgpl.shtml |
-- |
------------------------------------------------------------------------------- |
-- Revision history. |
-- - Adding support for all sizes of maintenance packets. |
-- - Adding configAck to external config-space interface. |
------------------------------------------------------------------------------- |
|
|
------------------------------------------------------------------------------- |
117,7 → 117,8
configWe_o : out std_logic; |
configAddr_o : out std_logic_vector(23 downto 0); |
configData_o : out std_logic_vector(31 downto 0); |
configData_i : in std_logic_vector(31 downto 0)); |
configData_i : in std_logic_vector(31 downto 0); |
configAck_i : in std_logic); |
end entity; |
|
|
225,7 → 226,8
configWe_o : out std_logic; |
configAddr_o : out std_logic_vector(23 downto 0); |
configData_o : out std_logic_vector(31 downto 0); |
configData_i : in std_logic_vector(31 downto 0)); |
configData_i : in std_logic_vector(31 downto 0); |
configAck_i : in std_logic); |
end component; |
|
component SwitchPort is |
394,7 → 396,7
outboundAckId_o=>outboundAckId_o, inboundAckId_i=>inboundAckId_i, |
outstandingAckId_i=>outstandingAckId_i, outboundAckId_i=>outboundAckId_i, |
configStb_o=>configStb_o, configWe_o=>configWe_o, configAddr_o=>configAddr_o, |
configData_o=>configData_o, configData_i=>configData_i); |
configData_o=>configData_o, configData_i=>configData_i, configAck_i=>configAck_i); |
|
end architecture; |
|
905,7 → 907,8
configWe_o : out std_logic; |
configAddr_o : out std_logic_vector(23 downto 0); |
configData_o : out std_logic_vector(31 downto 0); |
configData_i : in std_logic_vector(31 downto 0)); |
configData_i : in std_logic_vector(31 downto 0); |
configAck_i : in std_logic); |
end entity; |
|
|
963,13 → 966,13
-- Signals between the port and the packet-queue. |
----------------------------------------------------------------------------- |
|
signal outboundFramePort : std_logic_vector(7 downto 0); |
signal outboundFramePort, outboundFramePort0 : std_logic_vector(7 downto 0); |
signal outboundReadFrameEmpty : std_logic; |
signal outboundReadFrame : std_logic; |
signal outboundReadContent : std_logic; |
signal outboundReadContentEnd : std_logic; |
signal outboundReadContentData : std_logic_vector(31 downto 0); |
signal inboundFramePort : std_logic_vector(7 downto 0); |
signal inboundFramePort, inboundFramePort0 : std_logic_vector(7 downto 0); |
signal inboundWriteFrameFull : std_logic; |
signal inboundWriteFrame : std_logic; |
signal inboundWriteFrameAbort : std_logic; |
1014,6 → 1017,7
signal prio : std_logic_vector(1 downto 0); |
signal tt : std_logic_vector(1 downto 0); |
signal tid : std_logic_vector(7 downto 0); |
signal status : std_logic_vector(3 downto 0); |
|
signal readRequestInbound : std_logic; |
signal writeRequestInbound : std_logic; |
1022,12 → 1026,14
signal portWriteInbound : std_logic; |
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 statusInbound : std_logic_vector(3 downto 0); |
signal hopInbound : std_logic_vector(7 downto 0); |
signal offsetInbound : std_logic_vector(20 downto 0); |
signal wdptrInbound: std_logic; |
signal payloadLengthInbound : std_logic_vector(3 downto 0); |
signal payloadIndexInbound : std_logic_vector(3 downto 0); |
signal payloadInbound : std_logic_vector(31 downto 0); |
signal payloadLengthInbound : std_logic_vector(2 downto 0); |
signal payloadIndexInbound : std_logic_vector(2 downto 0); |
signal payloadInbound : std_logic_vector(63 downto 0); |
signal doneInbound : std_logic; |
|
signal readRequestOutbound : std_logic; |
1037,11 → 1043,11
signal portWriteOutbound : std_logic; |
signal dstIdOutbound : std_logic_vector(31 downto 0); |
signal srcIdOutbound : std_logic_vector(31 downto 0); |
signal statusOutbound : std_logic_vector(3 downto 0); |
signal hopOutbound : std_logic_vector(7 downto 0); |
signal wdptrOutbound: std_logic; |
signal payloadLengthOutbound : std_logic_vector(3 downto 0); |
signal payloadIndexOutbound : std_logic_vector(3 downto 0); |
signal payloadOutbound : std_logic_vector(31 downto 0); |
signal payloadLengthOutbound : std_logic_vector(2 downto 0); |
signal payloadIndexOutbound : std_logic_vector(2 downto 0); |
signal payloadOutbound : std_logic_vector(63 downto 0); |
signal doneOutbound : std_logic; |
|
signal readRequestMaint : std_logic; |
1048,10 → 1054,10
signal writeRequestMaint : std_logic; |
signal readResponseMaint : std_logic; |
signal writeResponseMaint : std_logic; |
signal wdptrMaint : std_logic; |
signal payloadLengthMaint : std_logic_vector(3 downto 0); |
signal payloadIndexMaint : std_logic_vector(3 downto 0); |
signal payloadMaint : std_logic_vector(31 downto 0); |
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; |
|
----------------------------------------------------------------------------- |
1082,12 → 1088,12
-- Configuration space signals. |
----------------------------------------------------------------------------- |
|
signal configStb : std_logic; |
signal configStb, configStbInternal : std_logic; |
signal configWe : std_logic; |
signal configAdr : std_logic_vector(23 downto 0); |
signal configDataWrite : std_logic_vector(31 downto 0); |
signal configDataRead, configDataReadInternal : std_logic_vector(31 downto 0); |
signal configAck : std_logic; |
signal configAck, configAckInternal : std_logic; |
|
-- REMARK: Make these variables instead... |
signal discovered : std_logic; |
1127,7 → 1133,7
slaveAck_o=>slaveAck_o, |
lookupStb_o=>open, |
lookupAddr_o=>open, |
lookupData_i=>outboundFramePort, |
lookupData_i=>outboundFramePort0, |
lookupAck_i=>'1', |
readFrameEmpty_i=>outboundReadFrameEmpty, |
readFrame_o=>outboundReadFrame, |
1137,7 → 1143,7
readContent_o=>outboundReadContent, |
readContentEnd_i=>outboundReadContentEnd, |
readContentData_i=>outboundReadContentData, |
writeFramePort_o=>inboundFramePort, |
writeFramePort_o=>inboundFramePort0, |
writeFrameFull_i=>inboundWriteFrameFull, |
writeFrame_o=>inboundWriteFrame, |
writeFrameAbort_o=>inboundWriteFrameAbort, |
1144,11 → 1150,24
writeContent_o=>inboundWriteContent, |
writeContentData_o=>inboundWriteContentData); |
|
process(clk) |
begin |
if (clk'event and clk = '1') then |
if (inboundReadFrame = '1') then |
inboundFramePort <= inboundFramePort0; |
end if; |
if (outboundWriteFrame = '1') then |
outboundFramePort0 <= outboundFramePort; |
end if; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- 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... |
PacketQueue: RioPacketBuffer |
generic map(SIZE_ADDRESS_WIDTH=>1, CONTENT_ADDRESS_WIDTH=>7) |
port map( |
1231,6 → 1250,8
tt_o=>tt, |
dstid_o=>dstIdInbound, |
srcid_o=>srcIdInbound, |
size_o=>sizeInbound, |
status_o=>statusInbound, |
tid_o=>tid, |
hop_o=>hopInbound, |
offset_o=>offsetInbound, |
1255,8 → 1276,8
portWriteOutbound <= (portWriteInbound and sendPacket) when (forwardPacket = '1') else '0'; |
srcIdOutbound <= srcIdInbound when (forwardPacket = '1') else dstIdInbound; |
dstIdOutbound <= dstIdInbound when (forwardPacket = '1') else srcIdInbound; |
statusOutbound <= statusInbound when (forwardPacket = '1') else statusMaint; |
hopOutbound <= std_logic_vector(unsigned(hopInbound)-1) when (forwardPacket = '1') else x"ff"; |
wdptrOutbound <= wdptrInbound when (forwardPacket = '1') else wdptrMaint; |
payloadLengthOutbound <= payloadLengthInbound when (forwardPacket = '1') else payloadLengthMaint; |
payloadOutbound <= payloadInbound when (forwardPacket = '1') else payloadMaint; |
-- REMARK: Connect enable to something... |
1274,11 → 1295,12
tt_i=>tt, |
dstid_i=>dstIdOutbound, |
srcid_i=>srcIdOutbound, |
status_i=>"0000", |
size_i=>sizeInbound, |
status_i=>statusOutbound, |
tid_i=>tid, |
hop_i=>hopOutbound, |
offset_i=>offsetInbound, |
wdptr_i=>wdptrOutbound, |
wdptr_i=>wdptrInbound, |
payloadLength_i=>payloadLengthOutbound, |
payloadIndex_o=>payloadIndexOutbound, |
payload_i=>payloadOutbound, |
1368,7 → 1390,7
-- 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 (doneOutbound = '1') then |
if (doneInbound = '1') then |
masterState := STATE_IDLE; |
end if; |
|
1391,7 → 1413,8
port map( |
clk=>clk, areset_n=>areset_n, enable=>'1', |
readRequestReady_i=>readRequestMaint, |
writeRequestReady_i=>writeRequestMaint, |
writeRequestReady_i=>writeRequestMaint, |
size_i=>sizeInbound, |
offset_i=>offsetInbound, |
wdptr_i=>wdptrInbound, |
payloadLength_i=>payloadLengthInbound, |
1399,8 → 1422,8
payload_i=>payloadInbound, |
done_o=>doneMaint, |
readResponseReady_o=>readResponseMaint, |
writeResponseReady_o=>writeResponseMaint, |
wdptr_o=>wdptrMaint, |
writeResponseReady_o=>writeResponseMaint, |
status_o=>statusMaint, |
payloadLength_o=>payloadLengthMaint, |
payloadIndex_i=>payloadIndexOutbound, |
payload_o=>payloadMaint, |
1420,19 → 1443,19
outputPortEnable_o <= outputPortEnable; |
inputPortEnable_o <= inputPortEnable; |
|
-- REMARK: Connect configAck... |
configStb_o <= '1' when ((configStb = '1') and (configAdr(23 downto 16) /= x"00")) else '0'; |
configStbInternal <= '1' when ((configStb = '1') and (configAdr(23 downto 16) = x"00")) else '0'; |
configWe_o <= configWe; |
configAddr_o <= configAdr; |
configData_o <= configDataWrite; |
configDataRead <= configData_i when (configAdr(23 downto 16) /= x"00") else |
configDataReadInternal; |
configDataRead <= configData_i when (configStbInternal = '0') else configDataReadInternal; |
configAck <= configAck_i when (configStbInternal = '0') else configAckInternal; |
|
ConfigMemory: process(areset_n, clk) |
begin |
if (areset_n = '0') then |
configDataReadInternal <= (others => '0'); |
configAck <= '0'; |
configAckInternal <= '0'; |
|
routeTableEnable <= '1'; |
routeTableWrite <= '0'; |
1457,9 → 1480,9
routeTableWrite <= '0'; |
localAckIdWrite_o <= (others => '0'); |
|
if (configAck = '0') then |
if (configStb = '1') then |
configAck <= '1'; |
if (configAckInternal = '0') then |
if (configStbInternal = '1') then |
configAckInternal <= '1'; |
|
-- Check if the access is into implementation defined space or if the |
-- access should be handled here. |
1849,7 → 1872,7
-- Config memory not enabled. |
end if; |
else |
configAck <= '0'; |
configAckInternal <= '0'; |
end if; |
end if; |
end process; |
/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd
9,6 → 9,8
-- Contains a platform to build endpoints on. |
-- |
-- 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. |
-- - Egress; Place packets in different queues depending on the packet priority? |
44,6 → 46,7
-- |
------------------------------------------------------------------------------- |
|
|
------------------------------------------------------------------------------- |
-- RioLogicalCommon. |
------------------------------------------------------------------------------- |
66,7 → 69,7
|
|
------------------------------------------------------------------------------- |
-- |
-- Entity for RioLogicalCommon. |
------------------------------------------------------------------------------- |
entity RioLogicalCommon is |
generic( |
102,7 → 105,7
|
|
------------------------------------------------------------------------------- |
-- |
-- Architecture for RioLogicalCommon. |
------------------------------------------------------------------------------- |
architecture RioLogicalCommon of RioLogicalCommon is |
|
213,6 → 216,7
use ieee.numeric_std.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for RioLogicalCommonIngress. |
------------------------------------------------------------------------------- |
236,7 → 240,7
|
|
------------------------------------------------------------------------------- |
-- |
-- Architecture for RioLogicalCommonIngress. |
------------------------------------------------------------------------------- |
architecture RioLogicalCommonIngress of RioLogicalCommonIngress is |
type StateType is (IDLE, |
466,6 → 470,7
end architecture; |
|
|
|
------------------------------------------------------------------------------- |
-- RioLogicalCommonEgress. |
-- Only 8-bit and 16-bit deviceId are supported. The first write must contain |
479,6 → 484,7
use ieee.numeric_std.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- Entity for RioLogicalCommonEgress. |
------------------------------------------------------------------------------- |
734,20 → 740,15
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (packetPosition < 19) then |
if (packetPosition <= 19) then |
if (tt = "01") then |
writeContent <= '1'; |
writeContentData1 <= crc16Current & x"0000"; |
end if; |
elsif (packetPosition = 19) then |
if (tt = "01") then |
|
end if; |
else |
if (tt = "01") then |
writeContent <= '1'; |
writeContentData1 <= writeContentData2(31 downto 16) & crc16Temp; |
packetPosition <= packetPosition + 1; |
end if; |
end if; |
|
798,9 → 799,8
|
|
------------------------------------------------------------------------------- |
-- |
-- RioLogicalCommonIngress. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
808,7 → 808,7
|
|
------------------------------------------------------------------------------- |
-- |
-- Entity for RioLogicalCommonInterconnect. |
------------------------------------------------------------------------------- |
entity RioLogicalCommonInterconnect is |
generic( |
828,7 → 828,7
|
|
------------------------------------------------------------------------------- |
-- |
-- Architecture for RioLogicalCommonInterconnect. |
------------------------------------------------------------------------------- |
architecture RioLogicalCommonInterconnectImpl of RioLogicalCommonInterconnect is |
signal activeCycle : std_logic; |