URL
https://opencores.org/ocsvn/rio/rio/trunk
Subversion Repositories rio
Compare Revisions
- This comparison shows the changes necessary to convert path
/rio
- from Rev 44 to Rev 45
- ↔ Reverse comparison
Rev 44 → Rev 45
/branches/2.0.0-development/bench/vhdl/TestRioWbBridge.vhd
9,7 → 9,7
-- Contains automatic test code to verify a RioWbBridge implementation. |
-- |
-- To Do: |
-- - |
-- REMARK: Move the testport package and entities to a seperate file. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
42,7 → 42,6
------------------------------------------------------------------------------- |
|
|
-- REMARK: Move the testport package and entities to a seperate file. |
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
559,36 → 558,44
if (clk'event) then |
if (cyc_i = '1') then |
if (front /= back) then |
if (cyclePosition < queue(back).length) 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"); |
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; |
-- REMARK: Add this... |
--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; |
|
if (latencyCounter = queue(back).latency) then |
dat_o <= queue(back).data(cyclePosition); |
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 := 0; |
cyclePosition := cyclePosition + 1; |
latencyCounter := latencyCounter + 1; |
else |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
latencyCounter := latencyCounter + 1; |
latencyCounter := 0; |
cyclePosition := cyclePosition + 1; |
|
if (cyclePosition = queue(back).length) then |
back := QueueIndexInc(back); |
cyclePosition := 0; |
end if; |
end if; |
else |
back := QueueIndexInc(back); |
cyclePosition := 0; |
latencyCounter := 0; |
dat_o <= (others=>'U'); |
ack_o <= '0'; |
end if; |
else |
TestError("Unexpected access."); |
912,13 → 919,15
end function; |
|
--------------------------------------------------------------------------- |
-- |
-- Local variables. |
--------------------------------------------------------------------------- |
variable seed1 : positive := 1; |
variable seed2: positive := 1; |
|
variable rdsize : std_logic_vector(3 downto 0); |
variable wrsize : std_logic_vector(3 downto 0); |
variable wdptr : std_logic; |
variable maintData : DoubleWordArray(0 to 7); |
variable ioData : DoubleWordArray(0 to 31); |
variable frame : RioFrame; |
|
953,7 → 962,35
--------------------------------------------------------------------------- |
PrintR("TG_RioWbBridge-TC1-Step1"); |
--------------------------------------------------------------------------- |
|
InboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>x"dead", destId=>x"beef", |
payload=>RioMaintenance(transaction=>"0000", |
size=>"1000", |
tid=>x"aa", |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>0, |
data=>maintData))); |
|
maintData(0) := x"deadbeef00000000"; |
OutboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_MAINTENANCE_CLASS, |
sourceId=>x"beef", destId=>x"dead", |
payload=>RioMaintenance(transaction=>"0010", |
size=>"0000", |
tid=>x"aa", |
hopCount=>x"ff", |
configOffset=>"000000000000000000000", |
wdptr=>'0', |
dataLength=>1, |
data=>maintData))); |
|
TestWait(inboundEmpty, '1', "inbound frame"); |
TestWait(outboundEmpty, '1', "outbound frame"); |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioWbBridge-TC2"); |
961,13 → 998,13
PrintS("Requirement: XXXXX"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send maintenance read request for one word on even offset."); |
PrintS("Result: Check the accesses on the external configuration port."); |
PrintS("Action: Send request class NREAD packets for all sizes."); |
PrintS("Result: The Wishbone access should match the inbound packet."); |
PrintS("-----------------------------------------------------------------"); |
--------------------------------------------------------------------------- |
PrintR("TG_RioWbBridge-TC2-Step1"); |
--------------------------------------------------------------------------- |
-- REMARK: Change the address also... |
-- REMARK: Change the address and tid also... |
for i in 0 to 15 loop |
for j in 0 to 1 loop |
rdsize := std_logic_vector(to_unsigned(i, 4)); |
1008,6 → 1045,104
end loop; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("TG_RioWbBridge-TC3"); |
PrintS("Description: Test write class packets."); |
PrintS("Requirement: XXXXX"); |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 1:"); |
PrintS("Action: Send write class NWRITER packets for all sizes."); |
PrintS("Result: The Wishbone access should match the inbound packet and a "); |
PrintS(" response should be sent."); |
PrintS("-----------------------------------------------------------------"); |
--------------------------------------------------------------------------- |
PrintR("TG_RioWbBridge-TC3-Step1"); |
--------------------------------------------------------------------------- |
-- REMARK: Change the address and tid also... |
for i in 0 to 15 loop |
for j in 0 to 1 loop |
wrsize := std_logic_vector(to_unsigned(i, 4)); |
if (j = 0) then |
wdptr := '0'; |
else |
wdptr:= '1'; |
end if; |
|
CreateRandomPayload(ioData, seed1, seed2); |
|
InboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_WRITE_CLASS, |
sourceId=>x"dead", destId=>x"beef", |
payload=>RioNwriteR(wrsize=>wrsize, |
tid=>x"aa", |
address=>"00000000000000000000000000000", |
wdptr=>wdptr, |
xamsbs=>"00", |
dataLength=>getReadSize(wrsize, wdptr), |
data=>ioData))); |
|
OutboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_RESPONSE_CLASS, |
sourceId=>x"beef", destId=>x"dead", |
payload=>RioResponse(status=>"0000", |
tid=>x"aa", |
dataLength=>0, |
data=>ioData))); |
|
SetSlaveAccess(true, "0000000000000000000000000000000", |
getReadMask(wrsize, wdptr), |
getReadSize(wrsize, wdptr), |
ioData); |
|
TestWait(inboundEmpty, '1', "inbound frame"); |
TestWait(outboundEmpty, '1', "outbound frame"); |
TestWait(wbMessageEmpty, '1', "wishbone access"); |
end loop; |
end loop; |
|
--------------------------------------------------------------------------- |
PrintS("-----------------------------------------------------------------"); |
PrintS("Step 2:"); |
PrintS("Action: Send write class NWRITE packets for all sizes."); |
PrintS("Result: The Wishbone access should match the inbound packet."); |
PrintS("-----------------------------------------------------------------"); |
--------------------------------------------------------------------------- |
PrintR("TG_RioWbBridge-TC3-Step2"); |
--------------------------------------------------------------------------- |
-- REMARK: Change the address and tid also... |
for i in 0 to 15 loop |
for j in 0 to 1 loop |
wrsize := std_logic_vector(to_unsigned(i, 4)); |
if (j = 0) then |
wdptr := '0'; |
else |
wdptr:= '1'; |
end if; |
|
CreateRandomPayload(ioData, seed1, seed2); |
|
InboundFrame(RioFrameCreate(ackId=>"00000", vc=>'0', crf=>'0', prio=>"00", |
tt=>"01", ftype=>FTYPE_WRITE_CLASS, |
sourceId=>x"dead", destId=>x"beef", |
payload=>RioNwrite(wrsize=>wrsize, |
address=>"00000000000000000000000000000", |
wdptr=>wdptr, |
xamsbs=>"00", |
dataLength=>getReadSize(wrsize, wdptr), |
data=>ioData))); |
|
SetSlaveAccess(true, "0000000000000000000000000000000", |
getReadMask(wrsize, wdptr), |
getReadSize(wrsize, wdptr), |
ioData); |
|
TestWait(inboundEmpty, '1', "inbound frame"); |
TestWait(outboundEmpty, '1', "outbound frame"); |
TestWait(wbMessageEmpty, '1', "wishbone access"); |
end loop; |
end loop; |
|
--------------------------------------------------------------------------- |
-- Test completed. |
--------------------------------------------------------------------------- |
|
/branches/2.0.0-development/rtl/vhdl/RioWbBridge.vhd
10,7 → 10,26
-- NWRITE, NWRITER and NREAD are currently supported. |
-- |
-- To Do: |
-- - |
-- REMARK: Set the stb_o to '0' in between read accesses to conform better to a |
-- block transfer in the Wishbone standard. |
-- REMARK: Clean up cyc-signals, only stb-signals are needed (between |
-- RioLogicalCommon and the packet handlers). |
-- REMARK: Add support for the lock_o to be sure to transfer all the packet |
-- content atomically? |
-- REMARK: Add support for EXTENDED_ADDRESS. |
-- REMARK: Use the baseDeviceId when sending packets? Currently, all responses |
-- are sent with destination<->source exchanged so the baseDeviceId is not |
-- needed. |
-- REMARK: Support inbound data with full bandwidth, not just half, applies to |
-- RioLogicalCommon and the packet handlers. |
-- REMARK: Move the packet handlers to seperate files. |
-- REMARK: Increase the priority of the response-packet when sent? |
-- REMARK: Implement error indications if erronous packets are received. |
-- REMARK: Implement error indications if err_i is received on the Wishbone bus. |
-- REMARK: Add support for extended features to dynamically configure the status |
-- from the port this block is connected to. Needed for the discovered- and |
-- masterEnable-bits. |
-- REMARK: Add support for outbound doorbells connected to interrupt input pins. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
42,10 → 61,12
-- |
------------------------------------------------------------------------------- |
|
|
------------------------------------------------------------------------------- |
-- RioWbBridge. |
-- This block acts as an RapidIO endpoint and converts packets into Wishbone |
-- accesses. |
------------------------------------------------------------------------------- |
-- REMARK: Add support for EXTENDED_ADDRESS... |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
117,11 → 138,11
select_o : out std_logic_vector(7 downto 0); |
done_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end component; |
|
component WriteClassInbound is |
133,6 → 154,7
enable : in std_logic; |
|
ready_o : out std_logic; |
responseNeeded_o : out std_logic; |
vc_o : out std_logic; |
crf_o : out std_logic; |
prio_o : out std_logic_vector(1 downto 0); |
148,11 → 170,11
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end component; |
|
component ResponseClassOutbound is |
177,13 → 199,40
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end component; |
|
component RioLogicalMaintenance is |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
enable : 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; |
|
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic; |
|
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end component; |
|
component RioLogicalCommon is |
generic( |
PORTS : natural); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
201,21 → 250,23
writeContent_o : out std_logic; |
writeContentData_o : out std_logic_vector(31 downto 0); |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterAdr_o : out std_logic_vector(7 downto 0); |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic; |
inboundCyc_o : out std_logic; |
inboundStb_o : out std_logic; |
inboundAdr_o : out std_logic_vector(7 downto 0); |
inboundDat_o : out std_logic_vector(31 downto 0); |
inboundAck_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
outboundCyc_i : in std_logic_vector(PORTS-1 downto 0); |
outboundStb_i : in std_logic_vector(PORTS-1 downto 0); |
outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0); |
outboundAck_o : out std_logic_vector(PORTS-1 downto 0)); |
end component; |
|
constant PORTS : natural := 2; |
|
type StateType is (IDLE, |
REQUEST_CLASS, REQUEST_CLASS_RESPONSE, |
WRITE_CLASS, WRITE_CLASS_RESPONSE); |
WRITE_CLASS, WRITE_CLASS_ACCESS, WRITE_CLASS_ACK, WRITE_CLASS_RESPONSE); |
signal state : StateType; |
|
signal adr : std_logic_vector(16*EXTENDED_ADDRESS+30 downto 0); |
239,6 → 290,7
signal requestAck : std_logic; |
|
signal writeReady : std_logic; |
signal writeResponse : std_logic; |
signal writeVc : std_logic; |
signal writeCrf : std_logic; |
signal writePrio : std_logic_vector(1 downto 0); |
266,6 → 318,15
signal responsePayload : std_logic_vector(63 downto 0); |
signal responseDone : std_logic; |
|
signal configStb : std_logic; |
signal configWe : std_logic; |
signal configAdr : std_logic_vector(21 downto 0); |
signal configAdrByte : std_logic_vector(23 downto 0); |
signal configDatWrite : std_logic_vector(31 downto 0); |
signal configDatRead : std_logic_vector(31 downto 0); |
signal configAck : std_logic; |
signal maintenanceAck : std_logic; |
|
signal inboundCyc : std_logic; |
signal inboundStb : std_logic; |
signal inboundAdr : std_logic_vector(7 downto 0); |
272,22 → 333,10
signal inboundDat : std_logic_vector(31 downto 0); |
signal inboundAck : std_logic; |
|
signal outboundCyc : std_logic; |
signal outboundStb : std_logic; |
signal outboundDat : std_logic_vector(31 downto 0); |
signal outboundAck : std_logic; |
|
-- signal configStb : std_logic; |
-- signal configWe : std_logic; |
-- signal configAdr : std_logic_vector(23 downto 0); |
-- signal configDatWrite : std_logic_vector(31 downto 0); |
-- signal configDatRead : std_logic_vector(31 downto 0); |
-- signal configAck : std_logic; |
|
-- signal componentTag : std_logic_vector(31 downto 0); |
-- signal baseDeviceId : std_logic_vector(15 downto 0) := DEFAULT_BASE_DEVICE_ID; |
-- signal hostBaseDeviceIdLocked : std_logic; |
-- signal hostBaseDeviceId : std_logic_vector(15 downto 0) := (others => '1'); |
signal outboundCyc : std_logic_vector(PORTS-1 downto 0); |
signal outboundStb : std_logic_vector(PORTS-1 downto 0); |
signal outboundDat : std_logic_vector(32*PORTS-1 downto 0); |
signal outboundAck : std_logic_vector(PORTS-1 downto 0); |
|
begin |
|
353,12 → 402,7
responsePayloadPresent <= '1'; |
state <= REQUEST_CLASS; |
elsif (writeReady = '1') then |
cyc_o <= '1'; |
stb_o <= '1'; |
we_o <= '1'; |
adr <= writeAddress; |
sel_o <= writeSelect; |
datOut <= writePayload; |
|
payloadUpdate <= '1'; |
payloadIndex <= (others=>'0'); |
403,13 → 447,31
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
state <= WRITE_CLASS_ACCESS; |
|
when WRITE_CLASS_ACCESS => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
cyc_o <= '1'; |
stb_o <= '1'; |
we_o <= '1'; |
sel_o <= writeSelect; |
datOut <= writePayload; |
payloadUpdate <= '1'; |
|
state <= WRITE_CLASS_ACK; |
|
when WRITE_CLASS_ACK => |
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (ack_i = '1') then |
payloadUpdate <= '1'; |
|
adr <= std_logic_vector(unsigned(adr) + 1); |
|
if (payloadIndex /= writeLength) then |
datOut <= writePayload; |
if (unsigned(payloadIndex) /= (unsigned(writeLength)+2)) then |
stb_o <= '0'; |
state <= WRITE_CLASS_ACCESS; |
else |
writeDone <= '1'; |
cyc_o <= '0'; |
422,7 → 484,7
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (writeDone = '1') then |
if (responseDone = '1') or (writeResponse = '0') then |
responseReady <= '0'; |
state <= IDLE; |
else |
437,7 → 499,7
end process; |
|
----------------------------------------------------------------------------- |
-- |
-- Packet handlers. |
----------------------------------------------------------------------------- |
|
RequestClassInboundInst: RequestClassInbound |
459,11 → 521,11
length_o=>requestLength, |
select_o=>requestSelect, |
done_i=>requestDone, |
slaveCyc_i=>inboundCyc, |
slaveStb_i=>inboundStb, |
slaveAdr_i=>inboundAdr, |
slaveDat_i=>inboundDat, |
slaveAck_o=>requestAck); |
inboundCyc_i=>inboundCyc, |
inboundStb_i=>inboundStb, |
inboundAdr_i=>inboundAdr, |
inboundDat_i=>inboundDat, |
inboundAck_o=>requestAck); |
|
WriteClassInboundInst: WriteClassInbound |
generic map( |
473,6 → 535,7
areset_n=>areset_n, |
enable=>enable, |
ready_o=>writeReady, |
responseNeeded_o=>writeResponse, |
vc_o=>writeVc, |
crf_o=>writeCrf, |
prio_o=>writePrio, |
487,11 → 550,11
payloadIndex_i=>payloadIndex, |
payload_o=>writePayload, |
done_i=>writeDone, |
slaveCyc_i=>inboundCyc, |
slaveStb_i=>inboundStb, |
slaveAdr_i=>inboundAdr, |
slaveDat_i=>inboundDat, |
slaveAck_o=>writeAck); |
inboundCyc_i=>inboundCyc, |
inboundStb_i=>inboundStb, |
inboundAdr_i=>inboundAdr, |
inboundDat_i=>inboundDat, |
inboundAck_o=>writeAck); |
|
ResponseClassOutboundInst: ResponseClassOutbound |
port map( |
513,13 → 576,40
payloadIndex_i=>payloadIndex, |
payload_i=>responsePayload, |
done_o=>responseDone, |
masterCyc_o=>outboundCyc, |
masterStb_o=>outboundStb, |
masterDat_o=>outboundDat, |
masterAck_i=>outboundAck); |
outboundCyc_o=>outboundCyc(0), |
outboundStb_o=>outboundStb(0), |
outboundDat_o=>outboundDat(31 downto 0), |
outboundAck_i=>outboundAck(0)); |
|
inboundAck <= requestAck or writeAck; |
-- Maintenance packet processing. |
MaintenanceInst: RioLogicalMaintenance |
port map( |
clk=>clk, |
areset_n=>areset_n, |
enable=>enable, |
configStb_o=>configStb, |
configWe_o=>configWe, |
configAdr_o=>configAdr, |
configDat_o=>configDatWrite, |
configDat_i=>configDatRead, |
configAck_i=>configAck, |
inboundCyc_i=>inboundCyc, |
inboundStb_i=>inboundStb, |
inboundAdr_i=>inboundAdr, |
inboundDat_i=>inboundDat, |
inboundAck_o=>maintenanceAck, |
outboundCyc_o=>outboundCyc(1), |
outboundStb_o=>outboundStb(1), |
outboundDat_o=>outboundDat(63 downto 32), |
outboundAck_i=>outboundAck(1)); |
|
----------------------------------------------------------------------------- |
-- Common interface toward the packet queues. |
----------------------------------------------------------------------------- |
|
inboundAck <= requestAck or writeAck or maintenanceAck; |
RioLogicalCommonInst: RioLogicalCommon |
generic map(PORTS=>PORTS) |
port map( |
clk=>clk, |
areset_n=>areset_n, |
534,117 → 624,161
writeFrameAbort_o=>writeFrameAbort_o, |
writeContent_o=>writeContent_o, |
writeContentData_o=>writeContentData_o, |
masterCyc_o=>inboundCyc, |
masterStb_o=>inboundStb, |
masterAdr_o=>inboundAdr, |
masterDat_o=>inboundDat, |
masterAck_i=>inboundAck, |
slaveCyc_i=>outboundCyc, |
slaveStb_i=>outboundStb, |
slaveDat_i=>outboundDat, |
slaveAck_o=>outboundAck); |
inboundCyc_o=>inboundCyc, |
inboundStb_o=>inboundStb, |
inboundAdr_o=>inboundAdr, |
inboundDat_o=>inboundDat, |
inboundAck_i=>inboundAck, |
outboundCyc_i=>outboundCyc, |
outboundStb_i=>outboundStb, |
outboundDat_i=>outboundDat, |
outboundAck_o=>outboundAck); |
|
----------------------------------------------------------------------------- |
-- Configuration memory. |
----------------------------------------------------------------------------- |
-- memoryConfig : process(clk, areset_n) |
-- begin |
-- if (areset_n = '0') then |
-- configDataRead <= (others => '0'); |
-- baseDeviceId <= DEFAULT_BASE_DEVICE_ID; |
-- componentTag <= (others => '0'); |
-- hostBaseDeviceIdLocked <= '0'; |
-- hostBaseDeviceId <= (others => '1'); |
-- elsif (clk'event and clk = '1') then |
configAdrByte <= configAdr & "00"; |
memoryConfig : process(clk, areset_n) |
variable componentTag : std_logic_vector(31 downto 0); |
variable hostBaseDeviceIdLocked : std_logic; |
variable hostBaseDeviceId : std_logic_vector(15 downto 0); |
begin |
if (areset_n = '0') then |
componentTag := (others => '0'); |
hostBaseDeviceIdLocked := '0'; |
hostBaseDeviceId := (others => '1'); |
|
-- if (configEnable = '1') then |
-- case (configAddress) is |
-- when x"000000" => |
-- -- Device Identity CAR. Read-only. |
-- configDataRead(31 downto 16) <= DEVICE_IDENTITY; |
-- configDataRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY; |
-- when x"000004" => |
-- -- Device Information CAR. Read-only. |
-- configDataRead(31 downto 0) <= DEVICE_REV; |
-- when x"000008" => |
-- -- Assembly Identity CAR. Read-only. |
-- configDataRead(31 downto 16) <= ASSY_IDENTITY; |
-- configDataRead(15 downto 0) <= ASSY_VENDOR_IDENTITY; |
-- when x"00000c" => |
-- -- Assembly Informaiton CAR. Read-only. |
-- -- Extended features pointer to "0000". |
-- configDataRead(31 downto 16) <= ASSY_REV; |
-- configDataRead(15 downto 0) <= x"0000"; |
-- when x"000010" => |
-- -- Processing Element Features CAR. Read-only. |
-- -- Bridge(31), Memory(30), Processor(29), Switch(28). |
-- configDataRead(31) <= '1'; |
-- configDataRead(30 downto 4) <= (others => '0'); |
-- configDataRead(3) <= '1'; -- support 16 bits common transport large system |
-- configDataRead(2 downto 0) <= "001"; -- support 34 bits address |
-- when x"000018" => |
-- -- Source Operations CAR. Read-only. |
-- configDataRead(31 downto 0) <= (others => '0'); |
-- when x"00001C" => |
-- -- Destination Operations CAR. Read-only. |
-- configDataRead(31 downto 16) <= (others => '0'); |
-- configDataRead(15) <= '1'; |
-- configDataRead(14) <= '1'; |
-- configDataRead(13 downto 0) <= (others => '0'); |
-- when x"00004C" => |
-- -- Processing Element Logical Layer Control CSR. |
-- configDataRead(31 downto 3) <= (others => '0'); |
-- configDataRead(2 downto 0) <= "001"; -- support 34 bits address |
-- when x"000060" => |
-- -- Base Device ID CSR. |
-- -- Only valid for end point devices. |
-- if (configWrite = '1') then |
-- baseDeviceId <= configDataWrite(15 downto 0); |
-- else |
-- configDataRead(15 downto 0) <= baseDeviceId; |
-- end if; |
-- when x"000068" => |
-- -- Host Base Device ID Lock CSR. |
-- if (configWrite = '1') then |
-- -- Check if this field has been written before. |
-- if (hostBaseDeviceIdLocked = '0') then |
-- -- The field has not been written. |
-- -- Lock the field and set the host base device id. |
-- hostBaseDeviceIdLocked <= '1'; |
-- hostBaseDeviceId <= configDataWrite(15 downto 0); |
-- else |
-- -- The field has been written. |
-- -- Check if the written data is the same as the stored. |
-- if (hostBaseDeviceId = configDataWrite(15 downto 0)) then |
-- -- Same as stored, reset the value to its initial value. |
-- hostBaseDeviceIdLocked <= '0'; |
-- hostBaseDeviceId <= (others => '1'); |
-- else |
-- -- Not writing the same as the stored value. |
-- -- Ignore the write. |
-- end if; |
-- end if; |
-- else |
-- configDataRead(31 downto 16) <= (others => '0'); |
-- configDataRead(15 downto 0) <= hostBaseDeviceId; |
-- end if; |
-- when x"00006C" => |
-- -- Component TAG CSR. |
-- if (configWrite = '1') then |
-- componentTag <= configDataWrite; |
-- else |
-- configDataRead <= componentTag; |
-- end if; |
configDatRead <= (others => '0'); |
configAck <= '0'; |
elsif (clk'event and clk = '1') then |
if (configAck = '0') then |
if (configStb = '1') then |
configAck <= '1'; |
configDatRead <= (others=>'0'); |
|
-- Check the address the access is for. |
case (configAdrByte) is |
when x"000000" => |
----------------------------------------------------------------- |
-- Device Identity CAR. Read-only. |
----------------------------------------------------------------- |
configDatRead(31 downto 16) <= DEVICE_IDENTITY; |
configDatRead(15 downto 0) <= DEVICE_VENDOR_IDENTITY; |
|
when x"000004" => |
----------------------------------------------------------------- |
-- Device Information CAR. Read-only. |
----------------------------------------------------------------- |
configDatRead(31 downto 0) <= DEVICE_REV; |
|
when x"000008" => |
----------------------------------------------------------------- |
-- Assembly Identity CAR. Read-only. |
----------------------------------------------------------------- |
configDatRead(31 downto 16) <= ASSY_IDENTITY; |
configDatRead(15 downto 0) <= ASSY_VENDOR_IDENTITY; |
|
when x"00000c" => |
----------------------------------------------------------------- |
-- Assembly Information CAR. Read-only. |
----------------------------------------------------------------- |
configDatRead(31 downto 16) <= ASSY_REV; |
|
when x"000010" => |
----------------------------------------------------------------- |
-- Processing Element Features CAR. Read-only. |
----------------------------------------------------------------- |
-- Bridge. |
configDatRead(31) <= '1'; |
-- Extended addressing support, 34-bit addresses. |
configDatRead(2 downto 0) <= "001"; |
|
when x"000018" => |
----------------------------------------------------------------- |
-- Source Operations CAR. Read-only. |
----------------------------------------------------------------- |
-- Cannot act as a source of any packets. |
|
when x"00001c" => |
----------------------------------------------------------------- |
-- Destination Operations CAR. Read-only. |
----------------------------------------------------------------- |
-- Read, supported. |
configDatRead(15) <= '1'; |
-- Write, supported. |
configDatRead(14) <= '1'; |
-- Write-with-response, supported. |
configDatRead(12) <= '1'; |
|
when x"00004c" => |
----------------------------------------------------------------- |
-- Processing Element Logical Layer Control CSR. |
----------------------------------------------------------------- |
-- Extended addressing control, PE supports 34 bits addresses. |
configDatRead(2 downto 0) <= "001"; |
|
-- when others => |
-- configDataRead <= (others => '0'); |
-- end case; |
-- else |
-- -- Config memory not enabled. |
-- end if; |
-- end if; |
-- end process; |
when x"000060" => |
----------------------------------------------------------------- |
-- Base Device ID CSR. |
----------------------------------------------------------------- |
-- This is not used since this endpoint only replies to packets |
-- and it can then use the destination deviceId as a source. |
|
when x"000068" => |
----------------------------------------------------------------- |
-- Host Base Device ID Lock CSR. |
----------------------------------------------------------------- |
|
-- Check if writing. |
if (configWe = '1') then |
-- Write access. |
|
-- Check if this field has been written before. |
if (hostBaseDeviceIdLocked = '0') then |
-- The field has not been written. |
-- Lock the field and set the host base device id. |
hostBaseDeviceIdLocked := '1'; |
hostBaseDeviceId := configDatWrite(15 downto 0); |
else |
-- The field has been written. |
-- Check if the written data is the same as the stored. |
if (hostBaseDeviceId = configDatWrite(15 downto 0)) then |
-- Same as stored, reset the value to its initial value. |
hostBaseDeviceIdLocked := '0'; |
hostBaseDeviceId := (others => '1'); |
else |
-- Not writing the same as the stored value. |
-- Ignore the write. |
end if; |
end if; |
end if; |
|
configDatRead(15 downto 0) <= hostBaseDeviceId; |
|
when x"00006C" => |
----------------------------------------------------------------- |
-- Component TAG CSR. |
----------------------------------------------------------------- |
if (configWe = '1') then |
componentTag := configDatWrite; |
end if; |
|
configDatRead <= componentTag; |
|
when others => |
----------------------------------------------------------------- |
-- Other access. |
----------------------------------------------------------------- |
-- Respond with all zeros. |
configDatRead <= (others => '0'); |
end case; |
end if; |
else |
configAck <= '0'; |
end if; |
end if; |
end process; |
|
end architecture; |
|
|
682,11 → 816,11
select_o : out std_logic_vector(7 downto 0); |
done_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end entity; |
|
|
700,14 → 834,14
signal rdsize : std_logic_vector(3 downto 0); |
signal wdptr : std_logic; |
|
signal slaveAck : std_logic; |
signal inboundAck : std_logic; |
signal complete : std_logic; |
|
signal packetIndex : natural range 0 to 68; |
signal packetIndex : natural range 0 to 69; |
|
begin |
|
slaveAck_o <= slaveAck; |
inboundAck_o <= inboundAck; |
|
ready_o <= complete when (state = READY) else '0'; |
|
719,7 → 853,7
rdsize <= (others=>'0'); |
wdptr <= '0'; |
|
slaveAck <= '0'; |
inboundAck <= '0'; |
complete <= '0'; |
|
packetIndex <= 0; |
739,10 → 873,10
-- This state waits for a new REQUEST class packet, receives it |
-- and parses it. |
--------------------------------------------------------------------- |
if (slaveCyc_i = '1') then |
if (slaveAck = '0') then |
if (slaveStb_i = '1') then |
if (slaveAdr_i = x"24") then |
if (inboundCyc_i = '1') then |
if (inboundAck = '0') then |
if (inboundStb_i = '1') then |
if (inboundAdr_i = x"24") then |
------------------------------------------------------------- |
-- NREAD packet parser. |
------------------------------------------------------------- |
749,31 → 883,30
case (packetIndex) is |
when 0 => |
-- x"0000" & ackid & vc & crf & prio & tt & ftype |
vc_o <= slaveDat_i(9); |
crf_o <= slaveDat_i(8); |
prio_o <= slaveDat_i(7 downto 6); |
tt_o <= slaveDat_i(5 downto 4); |
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 <= slaveDat_i; |
dstId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- srcid |
srcId_o <= slaveDat_i; |
srcId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction(3:0) & rdsize(3:0) & srcTID(7:0) & address(28:13) |
-- REMARK: Add support for extended addresses here... |
rdsize <= slaveDat_i(27 downto 24); |
tid_o <= slaveDat_i(23 downto 16); |
address_o(28 downto 13) <= slaveDat_i(15 downto 0); |
rdsize <= inboundDat_i(27 downto 24); |
tid_o <= inboundDat_i(23 downto 16); |
address_o(28 downto 13) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
when 4 => |
-- address(12:0) & wdptr & xamsbs(1:0) & crc(15:0) |
address_o(12 downto 0) <= slaveDat_i(31 downto 19); |
wdptr <= slaveDat_i(18); |
address_o(30 downto 29) <= slaveDat_i(17 downto 16); |
address_o(12 downto 0) <= inboundDat_i(31 downto 19); |
wdptr <= inboundDat_i(18); |
address_o(30 downto 29) <= inboundDat_i(17 downto 16); |
packetIndex <= packetIndex + 1; |
complete <= '1'; |
when others => |
780,11 → 913,11
-- There should be no more content in an NREAD. |
-- Discard. |
end case; |
slaveAck <= '1'; |
inboundAck <= '1'; |
end if; |
end if; |
else |
slaveAck <= '0'; |
inboundAck <= '0'; |
end if; |
else |
if (complete = '1') then |
936,7 → 1069,6
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
-- REMARK: Support inbound data with full bandwidth, not just half... |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
955,6 → 1087,7
enable : in std_logic; |
|
ready_o : out std_logic; |
responseNeeded_o : out std_logic; |
vc_o : out std_logic; |
crf_o : out std_logic; |
prio_o : out std_logic_vector(1 downto 0); |
970,11 → 1103,11
payload_o : out std_logic_vector(63 downto 0); |
done_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end entity; |
|
|
1004,10 → 1137,10
signal wdptr : std_logic; |
signal wrsize : std_logic_vector(3 downto 0); |
|
signal slaveAck : std_logic; |
signal inboundAck : std_logic; |
signal complete : std_logic; |
|
signal packetIndex : natural range 0 to 68; |
signal packetIndex : natural range 0 to 69; |
|
signal doubleWord : std_logic_vector(63 downto 16); |
|
1018,7 → 1151,7
|
begin |
|
slaveAck_o <= slaveAck; |
inboundAck_o <= inboundAck; |
|
ready_o <= complete when (state = READY) else '0'; |
|
1030,8 → 1163,9
wdptr <= '0'; |
wrsize <= (others=>'0'); |
|
slaveAck <= '0'; |
inboundAck <= '0'; |
complete <= '0'; |
responseNeeded_o <= '0'; |
|
packetIndex <= 0; |
doubleWord <= (others=>'0'); |
1051,66 → 1185,66
elsif (clk'event and clk = '1') then |
case state is |
when RECEIVE_PACKET => |
--------------------------------------------------------------------- |
-- This state waits for a new WRITE class packet, receives it |
-- and parses it. |
--------------------------------------------------------------------- |
if (slaveCyc_i = '1') then |
if (slaveAck = '0') then |
if (slaveStb_i = '1') then |
if (slaveAdr_i = x"55") then |
if (inboundCyc_i = '1') then |
if (inboundAck = '0') then |
if (inboundStb_i = '1') then |
if ((inboundAdr_i = x"55") or (inboundAdr_i = x"54")) then |
------------------------------------------------------------- |
-- NWRITER packet parser. |
-- NWRITE/NWRITER packet parser. |
------------------------------------------------------------- |
-- REMARK: Add support for NWRITE without response... |
case (packetIndex) is |
when 0 => |
-- x"0000" & ackid & vc & crf & prio & tt & ftype |
vc_o <= slaveDat_i(9); |
crf_o <= slaveDat_i(8); |
prio_o <= slaveDat_i(7 downto 6); |
tt_o <= slaveDat_i(5 downto 4); |
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 <= slaveDat_i; |
dstId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- srcId |
srcId_o <= slaveDat_i; |
srcId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & wrsize & srcTID & address(28:13) |
-- REMARK: Add support for extended addresses here... |
wrsize <= slaveDat_i(27 downto 24); |
tid_o <= slaveDat_i(23 downto 16); |
address_o(28 downto 13) <= slaveDat_i(15 downto 0); |
if (inboundDat_i(31 downto 28) = "0101") then |
responseNeeded_o <= '1'; |
else |
responseNeeded_o <= '0'; |
end if; |
wrsize <= inboundDat_i(27 downto 24); |
tid_o <= inboundDat_i(23 downto 16); |
address_o(28 downto 13) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
when 4 => |
-- address(12:0) & wdptr & xamsbs(1:0) & double-word(63:48) |
address_o(12 downto 0) <= slaveDat_i(31 downto 19); |
wdptr <= slaveDat_i(18); |
doubleWord(63 downto 48) <= slaveDat_i(15 downto 0); |
address_o(12 downto 0) <= inboundDat_i(31 downto 19); |
wdptr <= inboundDat_i(18); |
address_o(30 downto 29) <= inboundDat_i(17 downto 16); |
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 | |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 => |
-- double-word(47:16) |
doubleWord(31 downto 16) <= slaveDat_i(15 downto 0); |
doubleWord(47 downto 16) <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 => |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 => |
-- double-word(15:0) & double-word(63:48) |
doubleWord(63 downto 48) <= slaveDat_i(15 downto 0); |
doubleWord(63 downto 48) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
|
memoryWrite <= '1'; |
memoryDataIn <= doubleWord(63 downto 16) & slaveDat_i(31 downto 16); |
complete <= '1'; |
memoryDataIn <= doubleWord(63 downto 16) & inboundDat_i(31 downto 16); |
when others => |
-- There should be no more content in an NWRITE request. |
-- There should be no more content in an NWRITE/NWRITER request. |
-- Discard. |
end case; |
slaveAck <= '1'; |
inboundAck <= '1'; |
end if; |
end if; |
else |
1119,14 → 1253,16
end if; |
|
memoryWrite <= '0'; |
slaveAck <= '0'; |
inboundAck <= '0'; |
end if; |
else |
if (complete = '1') then |
if (packetIndex >= 6) then |
complete <= '1'; |
state <= READY; |
else |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
end if; |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
end if; |
|
when READY => |
1135,6 → 1271,8
-- processed. |
--------------------------------------------------------------------- |
if (done_i = '1') then |
packetIndex <= 0; |
memoryAddress <= (others=>'0'); |
complete <= '0'; |
state <= RECEIVE_PACKET; |
end if; |
1198,7 → 1336,7
length_o <= "00000"; |
select_o <= "11111111"; |
when others => |
length_o <= memoryAddress; |
length_o <= std_logic_vector(unsigned(memoryAddress)-1); |
select_o <= "11111111"; |
end case; |
else |
1237,7 → 1375,7
length_o <= "00000"; |
select_o <= "01111111"; |
when others => |
length_o <= memoryAddress; |
length_o <= std_logic_vector(unsigned(memoryAddress)-1); |
select_o <= "11111111"; |
end case; |
end if; |
1297,10 → 1435,10
payload_i : in std_logic_vector(63 downto 0); |
done_o : out std_logic; |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end entity; |
|
|
1358,9 → 1496,9
|
done_o <= '0'; |
|
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
masterDat_o <= (others=>'0'); |
outboundCyc_o <= '0'; |
outboundStb_o <= '0'; |
outboundDat_o <= (others=>'0'); |
elsif (clk'event and clk = '1') then |
if (enable = '1') then |
case state is |
1369,9 → 1507,9
-- |
------------------------------------------------------------------- |
if (ready_i = '1') then |
masterCyc_o <= '1'; |
masterStb_o <= '1'; |
masterDat_o <= header; |
outboundCyc_o <= '1'; |
outboundStb_o <= '1'; |
outboundDat_o <= header; |
|
packetIndex <= 1; |
responsePayloadIndex <= (others=>'0'); |
1386,27 → 1524,27
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (outboundAck_i = '1') then |
case (packetIndex) is |
when 1 => |
-- destination |
masterDat_o <= dstId_i; |
outboundDat_o <= dstId_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- source |
masterDat_o <= srcId_i; |
outboundDat_o <= srcId_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & status & targetTID & double-word0(63:48) |
if (error_i = '0') then |
if (payloadPresent_i = '0') then |
masterDat_o <= "0000" & "0000" & tid_i & x"0000"; |
outboundDat_o <= "0000" & "0000" & tid_i & x"0000"; |
state <= WAIT_COMPLETE; |
else |
masterDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48); |
outboundDat_o <= "1000" & "0000" & tid_i & memoryDataRead(63 downto 48); |
end if; |
else |
masterDat_o <= "0000" & "0111" & tid_i & x"0000"; |
outboundDat_o <= "0000" & "0111" & tid_i & x"0000"; |
state <= WAIT_COMPLETE; |
end if; |
packetIndex <= packetIndex + 1; |
1413,7 → 1551,7
when 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | |
36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 => |
-- double-wordN(47:16) |
masterDat_o <= memoryDataRead(47 downto 16); |
outboundDat_o <= memoryDataRead(47 downto 16); |
responsePayload <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
packetIndex <= packetIndex + 1; |
1420,7 → 1558,7
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 | 35 | |
37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 | 55 | 57 | 59 | 61 | 63 | 65 | 67 => |
-- double-wordN(15:0) & double-wordN(63:48) |
masterDat_o <= responsePayload & memoryDataRead(63 downto 48); |
outboundDat_o <= responsePayload & memoryDataRead(63 downto 48); |
packetIndex <= packetIndex + 1; |
|
responsePayloadIndex <= |
1441,9 → 1579,9
------------------------------------------------------------------- |
-- |
------------------------------------------------------------------- |
if (masterAck_i = '1') then |
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
if (outboundAck_i = '1') then |
outboundCyc_o <= '0'; |
outboundStb_o <= '0'; |
state <= RESPONSE_DONE; |
end if; |
|
/branches/2.0.0-development/rtl/vhdl/RioCommon.vhd
220,6 → 220,18
--------------------------------------------------------------------------- |
function RioNwrite( |
constant wrsize : in std_logic_vector(3 downto 0); |
constant address : in std_logic_vector(28 downto 0); |
constant wdptr : in std_logic; |
constant xamsbs : in std_logic_vector(1 downto 0); |
constant dataLength : in natural range 1 to 32; |
constant data : in DoublewordArray(0 to 31)) |
return RioPayload; |
|
--------------------------------------------------------------------------- |
-- Create a NWRITER RapidIO frame. |
--------------------------------------------------------------------------- |
function RioNwriteR( |
constant wrsize : in std_logic_vector(3 downto 0); |
constant tid : in std_logic_vector(7 downto 0); |
constant address : in std_logic_vector(28 downto 0); |
constant wdptr : in std_logic; |
584,7 → 596,6
----------------------------------------------------------------------------- |
function RioNwrite( |
constant wrsize : in std_logic_vector(3 downto 0); |
constant tid : in std_logic_vector(7 downto 0); |
constant address : in std_logic_vector(28 downto 0); |
constant wdptr : in std_logic; |
constant xamsbs : in std_logic_vector(1 downto 0); |
595,6 → 606,42
begin |
payload.data(0)(15 downto 12) := "0100"; |
payload.data(0)(11 downto 8) := wrsize; |
payload.data(0)(7 downto 0) := (others=>'0'); |
|
payload.data(1) := address(28 downto 13); |
|
payload.data(2)(15 downto 3) := address(12 downto 0); |
payload.data(2)(2) := wdptr; |
payload.data(2)(1 downto 0) := xamsbs; |
|
for i in 0 to dataLength-1 loop |
payload.data(3+4*i) := data(i)(63 downto 48); |
payload.data(4+4*i) := data(i)(47 downto 32); |
payload.data(5+4*i) := data(i)(31 downto 16); |
payload.data(6+4*i) := data(i)(15 downto 0); |
end loop; |
|
payload.length := 3 + 4*dataLength; |
|
return payload; |
end function; |
|
----------------------------------------------------------------------------- |
-- |
----------------------------------------------------------------------------- |
function RioNwriteR( |
constant wrsize : in std_logic_vector(3 downto 0); |
constant tid : in std_logic_vector(7 downto 0); |
constant address : in std_logic_vector(28 downto 0); |
constant wdptr : in std_logic; |
constant xamsbs : in std_logic_vector(1 downto 0); |
constant dataLength : in natural range 1 to 32; |
constant data : in DoublewordArray(0 to 31)) |
return RioPayload is |
variable payload : RioPayload; |
begin |
payload.data(0)(15 downto 12) := "0101"; |
payload.data(0)(11 downto 8) := wrsize; |
payload.data(0)(7 downto 0) := tid; |
|
payload.data(1) := address(28 downto 13); |
/branches/2.0.0-development/rtl/vhdl/RioLogicalMaintenance.vhd
9,7 → 9,9
-- Contains a platform to build endpoints on. |
-- |
-- To Do: |
-- - |
-- REMARK: Dont set complete before the packet is ready in inbound packet |
-- handler. |
-- REMARK: Add error indication if erronous sizes are received. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
70,16 → 72,16
configDat_i : in std_logic_vector(31 downto 0); |
configAck_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic; |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic; |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end entity; |
|
|
110,11 → 112,11
requestPayload_o : out std_logic_vector(31 downto 0); |
requestDone_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end component; |
|
component MaintenanceResponseOutbound is |
139,10 → 141,10
responsePayload_i : in std_logic_vector(31 downto 0); |
responseDone_o : out std_logic; |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end component; |
|
type StateType is (IDLE, |
315,11 → 317,11
requestPayloadIndex_i=>requestPayloadIndex, |
requestPayload_o=>requestPayload, |
requestDone_i=>requestDone, |
slaveCyc_i=>slaveCyc_i, |
slaveStb_i=>slaveStb_i, |
slaveAdr_i=>slaveAdr_i, |
slaveDat_i=>slaveDat_i, |
slaveAck_o=>slaveAck_o); |
inboundCyc_i=>inboundCyc_i, |
inboundStb_i=>inboundStb_i, |
inboundAdr_i=>inboundAdr_i, |
inboundDat_i=>inboundDat_i, |
inboundAck_o=>inboundAck_o); |
|
----------------------------------------------------------------------------- |
-- Response packet handler. |
344,10 → 346,10
responsePayloadIndex_i=>responsePayloadIndex, |
responsePayload_i=>configDat_i, |
responseDone_o=>responseDone, |
masterCyc_o=>masterCyc_o, |
masterStb_o=>masterStb_o, |
masterDat_o=>masterDat_o, |
masterAck_i=>masterAck_i); |
outboundCyc_o=>outboundCyc_o, |
outboundStb_o=>outboundStb_o, |
outboundDat_o=>outboundDat_o, |
outboundAck_i=>outboundAck_i); |
|
end architecture; |
|
386,11 → 388,11
requestPayload_o : out std_logic_vector(31 downto 0); |
requestDone_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveAdr_i : in std_logic_vector(7 downto 0); |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
inboundCyc_i : in std_logic; |
inboundStb_i : in std_logic; |
inboundAdr_i : in std_logic_vector(7 downto 0); |
inboundDat_i : in std_logic_vector(31 downto 0); |
inboundAck_o : out std_logic); |
end entity; |
|
|
421,7 → 423,7
signal size : std_logic_vector(3 downto 0); |
signal words : natural range 0 to 32; |
|
signal slaveAck : std_logic; |
signal inboundAck : std_logic; |
signal maintReadComplete : std_logic; |
signal maintWriteComplete : std_logic; |
|
434,7 → 436,7
|
begin |
|
slaveAck_o <= slaveAck; |
inboundAck_o <= inboundAck; |
|
requestReadReady_o <= maintReadComplete when (state = READY) else '0'; |
requestWriteReady_o <= maintWriteComplete when (state = READY) else '0'; |
442,7 → 444,7
MaintenanceRequest: process(clk, areset_n) |
begin |
if (areset_n = '0') then |
slaveAck <= '0'; |
inboundAck <= '0'; |
|
maintReadComplete <= '0'; |
maintWriteComplete <= '0'; |
467,10 → 469,10
-- This state waits for a new maintenance request packet, receives it |
-- and parses it. |
--------------------------------------------------------------------- |
if (slaveCyc_i = '1') then |
if (slaveAck = '0') then |
if (slaveStb_i = '1') then |
if (slaveAdr_i = x"80") then |
if (inboundCyc_i = '1') then |
if (inboundAck = '0') then |
if (inboundStb_i = '1') then |
if (inboundAdr_i = x"80") then |
------------------------------------------------------------- |
-- Maintenance Read Request packet parser. |
------------------------------------------------------------- |
477,29 → 479,29
case (packetIndex) is |
when 0 => |
-- x"0000" & ackid & vc & crf & prio & tt & ftype |
requestVc_o <= slaveDat_i(9); |
requestCrf_o <= slaveDat_i(8); |
requestPrio_o <= slaveDat_i(7 downto 6); |
requestTt_o <= slaveDat_i(5 downto 4); |
requestVc_o <= inboundDat_i(9); |
requestCrf_o <= inboundDat_i(8); |
requestPrio_o <= inboundDat_i(7 downto 6); |
requestTt_o <= inboundDat_i(5 downto 4); |
packetIndex <= packetIndex + 1; |
when 1 => |
-- destid |
requestDstId_o <= slaveDat_i; |
requestDstId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- srcid |
requestSrcId_o <= slaveDat_i; |
requestSrcId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & rdsize & srcTID & hop & config_offset(20:13) |
size <= slaveDat_i(27 downto 24); |
requestTid_o <= slaveDat_i(23 downto 16); |
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0); |
size <= inboundDat_i(27 downto 24); |
requestTid_o <= inboundDat_i(23 downto 16); |
requestOffset_o(20 downto 13) <= inboundDat_i(7 downto 0); |
packetIndex <= packetIndex + 1; |
when 4 => |
-- config_offset(12:0) & wdptr & rsrv & crc(15:0) |
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19); |
wdptr <= slaveDat_i(18); |
requestOffset_o(12 downto 0) <= inboundDat_i(31 downto 19); |
wdptr <= inboundDat_i(18); |
packetIndex <= packetIndex + 1; |
maintReadComplete <= '1'; |
when others => |
506,7 → 508,8
-- There should be no more content in a maintenance read request. |
-- Discard. |
end case; |
elsif (slaveAdr_i = x"81") then |
inboundAck <= '1'; |
elsif (inboundAdr_i = x"81") then |
------------------------------------------------------------- |
-- Maintenance Write Request packet parser. |
------------------------------------------------------------- |
513,54 → 516,55
case (packetIndex) is |
when 0 => |
-- x"0000" & ackid & vc & crf & prio & tt & ftype |
requestVc_o <= slaveDat_i(9); |
requestCrf_o <= slaveDat_i(8); |
requestPrio_o <= slaveDat_i(7 downto 6); |
requestTt_o <= slaveDat_i(5 downto 4); |
requestVc_o <= inboundDat_i(9); |
requestCrf_o <= inboundDat_i(8); |
requestPrio_o <= inboundDat_i(7 downto 6); |
requestTt_o <= inboundDat_i(5 downto 4); |
packetIndex <= packetIndex + 1; |
when 1 => |
-- destId |
requestDstId_o <= slaveDat_i; |
requestDstId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- srcId |
requestSrcId_o <= slaveDat_i; |
requestSrcId_o <= inboundDat_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & wrsize & srcTID & hop & config_offset(20:13) |
size <= slaveDat_i(27 downto 24); |
requestTid_o <= slaveDat_i(23 downto 16); |
requestOffset_o(20 downto 13) <= slaveDat_i(7 downto 0); |
size <= inboundDat_i(27 downto 24); |
requestTid_o <= inboundDat_i(23 downto 16); |
requestOffset_o(20 downto 13) <= inboundDat_i(7 downto 0); |
packetIndex <= packetIndex + 1; |
when 4 => |
-- config_offset(12:0) & wdptr & rsrv & double-word(63:48) |
requestOffset_o(12 downto 0) <= slaveDat_i(31 downto 19); |
wdptr <= slaveDat_i(18); |
requestData(31 downto 16) <= slaveDat_i(15 downto 0); |
requestOffset_o(12 downto 0) <= inboundDat_i(31 downto 19); |
wdptr <= inboundDat_i(18); |
requestData(31 downto 16) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => |
-- double-word(47:16) |
requestData(31 downto 16) <= slaveDat_i(15 downto 0); |
requestData(31 downto 16) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
|
if (not ((size = "1000") and (wdptr = '1'))) then |
memoryWrite <= '1'; |
memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16); |
memoryDataIn <= requestData(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 => |
-- double-word(15:0) & double-word(63:48) |
requestData(31 downto 16) <= slaveDat_i(15 downto 0); |
requestData(31 downto 16) <= inboundDat_i(15 downto 0); |
packetIndex <= packetIndex + 1; |
|
memoryWrite <= '1'; |
memoryDataIn <= requestData(31 downto 16) & slaveDat_i(31 downto 16); |
memoryDataIn <= requestData(31 downto 16) & inboundDat_i(31 downto 16); |
-- REMARK: Dont set complete before the packet is ready... |
maintWriteComplete <= '1'; |
when others => |
-- There should be no more content in a maintenance write request. |
-- Discard. |
end case; |
inboundAck <= '1'; |
end if; |
slaveAck <= '1'; |
end if; |
else |
if (memoryWrite = '1') then |
568,7 → 572,7
end if; |
|
memoryWrite <= '0'; |
slaveAck <= '0'; |
inboundAck <= '0'; |
end if; |
else |
if (maintReadComplete = '1') or (maintWriteComplete = '1') then |
680,7 → 684,6
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
-- REMARK: Add handler for maintenance response with error also... |
entity MaintenanceResponseOutbound is |
port( |
clk : in std_logic; |
703,10 → 706,10
responsePayload_i : in std_logic_vector(31 downto 0); |
responseDone_o : out std_logic; |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
outboundCyc_o : out std_logic; |
outboundStb_o : out std_logic; |
outboundDat_o : out std_logic_vector(31 downto 0); |
outboundAck_i : in std_logic); |
end entity; |
|
|
753,8 → 756,8
MaintenanceResponse: process(clk, areset_n) |
begin |
if (areset_n = '0') then |
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
outboundCyc_o <= '0'; |
outboundStb_o <= '0'; |
|
memoryEnable <= '0'; |
memoryAddress <= (others=>'0'); |
771,9 → 774,9
-- |
------------------------------------------------------------------- |
if (responseReadReady_i = '1') then |
masterCyc_o <= '1'; |
masterStb_o <= '1'; |
masterDat_o <= responseHeader; |
outboundCyc_o <= '1'; |
outboundStb_o <= '1'; |
outboundDat_o <= responseHeader; |
packetIndex <= 1; |
memoryEnable <= '1'; |
memoryAddress <= (others=>'0'); |
780,9 → 783,9
responsePayloadIndex <= (others=>'0'); |
state <= READ_RESPONSE; |
elsif (responseWriteReady_i = '1') then |
masterCyc_o <= '1'; |
masterStb_o <= '1'; |
masterDat_o <= responseHeader; |
outboundCyc_o <= '1'; |
outboundStb_o <= '1'; |
outboundDat_o <= responseHeader; |
packetIndex <= 1; |
state <= WRITE_RESPONSE; |
end if; |
791,30 → 794,30
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (outboundAck_i = '1') then |
case (packetIndex) is |
when 1 => |
-- destination |
masterDat_o <= responseDstId_i; |
outboundDat_o <= responseDstId_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- source |
masterDat_o <= responseSrcId_i; |
outboundDat_o <= responseSrcId_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & status & targetTID & hop & reserved(7:0) |
masterDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00"; |
outboundDat_o <= "0010" & "0000" & responseTid_i & x"ff" & x"00"; |
packetIndex <= packetIndex + 1; |
when 4 => |
-- reserved(15:0) & double-wordN(63:48) |
if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then |
masterDat_o <= x"0000" & memoryDataRead(31 downto 16); |
outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then |
masterDat_o <= x"0000" & x"0000"; |
outboundDat_o <= x"0000" & x"0000"; |
else |
masterDat_o <= x"0000" & memoryDataRead(31 downto 16); |
outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
end if; |
822,13 → 825,13
when 5 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 => |
-- double-wordN(47:16) |
if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then |
masterDat_o <= responsePayload(31 downto 16) & x"0000"; |
outboundDat_o <= responsePayload(31 downto 16) & x"0000"; |
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then |
masterDat_o <= x"0000" & memoryDataRead(31 downto 16); |
outboundDat_o <= x"0000" & memoryDataRead(31 downto 16); |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
else |
masterDat_o <= |
outboundDat_o <= |
responsePayload(31 downto 16) & memoryDataRead(31 downto 16); |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
837,17 → 840,17
when 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 => |
-- double-wordN(15:0) & double-wordN(63:48) |
if (responsePayloadLength_i = "0000") and (responseWdptr_i = '0') then |
masterDat_o <= x"0000" & x"0000"; |
outboundDat_o <= x"0000" & x"0000"; |
elsif (responsePayloadLength_i = "0000") and (responseWdptr_i = '1') then |
masterDat_o <= responsePayload(31 downto 16) & x"0000"; |
outboundDat_o <= responsePayload(31 downto 16) & x"0000"; |
else |
if (responsePayloadIndex /= responsePayloadLength_i(3 downto 1)) then |
masterDat_o <= |
outboundDat_o <= |
responsePayload(31 downto 16) & memoryDataRead(31 downto 16); |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
else |
masterDat_o <= |
outboundDat_o <= |
responsePayload(31 downto 16) & x"0000"; |
responsePayload(31 downto 16) <= memoryDataRead(15 downto 0); |
memoryAddress <= std_logic_vector(unsigned(memoryAddress) + 1); |
872,23 → 875,23
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (outboundAck_i = '1') then |
case (packetIndex) is |
when 1 => |
-- destination |
masterDat_o <= responseDstId_i; |
outboundDat_o <= responseDstId_i; |
packetIndex <= packetIndex + 1; |
when 2 => |
-- source |
masterDat_o <= responseSrcId_i; |
outboundDat_o <= responseSrcId_i; |
packetIndex <= packetIndex + 1; |
when 3 => |
-- transaction & status & targetTID & hop & reserved(7:0) |
masterDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00"; |
outboundDat_o <= "0011" & "0000" & responseTid_i & x"ff" & x"00"; |
packetIndex <= packetIndex + 1; |
when others => |
-- reserved(15:0) & crc(15:0) |
masterDat_o <= x"00000000"; |
outboundDat_o <= x"00000000"; |
packetIndex <= packetIndex + 1; |
state <= WAIT_COMPLETE; |
end case; |
898,9 → 901,9
------------------------------------------------------------------- |
-- |
------------------------------------------------------------------- |
if (masterAck_i = '1') then |
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
if (outboundAck_i = '1') then |
outboundCyc_o <= '0'; |
outboundStb_o <= '0'; |
state <= RESPONSE_DONE; |
end if; |
|
/branches/2.0.0-development/rtl/vhdl/RioLogicalCommon.vhd
9,7 → 9,10
-- Contains a platform to build endpoints on. |
-- |
-- To Do: |
-- - |
-- REMARK: Clean up and increase the speed of the interface to packet handlers. |
-- REMARK: 8-bit deviceId has not been verified, fix. |
-- REMARK: Egress; Places packets in different queues depending on the packet priority? |
-- REMARK: Add verification of all sizes of packets. |
-- |
-- Author(s): |
-- - Magnus Rosenius, magro732@opencores.org |
56,9 → 59,6
-- * Receives header and deviceIDs in seperate accesses to facilitate 8- and |
-- 16-bit deviceAddress support. All fields are right-justified. |
------------------------------------------------------------------------------- |
-- REMARK: Egress; Places packets in different queues depending on the packet priority? |
-- REMARK: Do not use Wishbone, use request/grant scheme instead? |
-- REMARK: 8-bit deviceId has not been verified, fix. |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
69,6 → 69,8
-- |
------------------------------------------------------------------------------- |
entity RioLogicalCommon is |
generic( |
PORTS : natural); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
86,16 → 88,16
writeContent_o : out std_logic; |
writeContentData_o : out std_logic_vector(31 downto 0); |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterAdr_o : out std_logic_vector(7 downto 0); |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic; |
inboundCyc_o : out std_logic; |
inboundStb_o : out std_logic; |
inboundAdr_o : out std_logic_vector(7 downto 0); |
inboundDat_o : out std_logic_vector(31 downto 0); |
inboundAck_i : in std_logic; |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
outboundCyc_i : in std_logic_vector(PORTS-1 downto 0); |
outboundStb_i : in std_logic_vector(PORTS-1 downto 0); |
outboundDat_i : in std_logic_vector(32*PORTS-1 downto 0); |
outboundAck_o : out std_logic_vector(PORTS-1 downto 0)); |
end entity; |
|
|
104,6 → 106,22
------------------------------------------------------------------------------- |
architecture RioLogicalCommon of RioLogicalCommon is |
|
component RioLogicalCommonInterconnect is |
generic( |
WIDTH : natural); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
stb_i : in std_logic_vector(WIDTH-1 downto 0); |
dataM_i : in std_logic_vector(32*WIDTH-1 downto 0); |
ack_o : out std_logic_vector(WIDTH-1 downto 0); |
|
stb_o : out std_logic; |
dataS_o : out std_logic_vector(31 downto 0); |
ack_i : in std_logic); |
end component; |
|
component RioLogicalCommonIngress is |
port( |
clk : in std_logic; |
115,11 → 133,11
readContentEnd_i : in std_logic; |
readContentData_i : in std_logic_vector(31 downto 0); |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterAdr_o : out std_logic_vector(7 downto 0); |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
inboundCyc_o : out std_logic; |
inboundStb_o : out std_logic; |
inboundAdr_o : out std_logic_vector(7 downto 0); |
inboundDat_o : out std_logic_vector(31 downto 0); |
inboundAck_i : in std_logic); |
end component; |
|
component RioLogicalCommonEgress is |
133,12 → 151,16
writeContent_o : out std_logic; |
writeContentData_o : out std_logic_vector(31 downto 0); |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
outboundCyc_i : in std_logic; |
outboundStb_i : in std_logic; |
outboundDat_i : in std_logic_vector(31 downto 0); |
outboundAck_o : out std_logic); |
end component; |
|
signal outboundStb : std_logic; |
signal outboundDat : std_logic_vector(31 downto 0); |
signal outboundAck : std_logic; |
|
begin |
|
Ingress: RioLogicalCommonIngress |
149,12 → 171,23
readContent_o=>readContent_o, |
readContentEnd_i=>readContentEnd_i, |
readContentData_i=>readContentData_i, |
masterCyc_o=>masterCyc_o, |
masterStb_o=>masterStb_o, |
masterAdr_o=>masterAdr_o, |
masterDat_o=>masterDat_o, |
masterAck_i=>masterAck_i); |
inboundCyc_o=>inboundCyc_o, |
inboundStb_o=>inboundStb_o, |
inboundAdr_o=>inboundAdr_o, |
inboundDat_o=>inboundDat_o, |
inboundAck_i=>inboundAck_i); |
|
EgressInterconnect: RioLogicalCommonInterconnect |
generic map(WIDTH=>PORTS) |
port map( |
clk=>clk, areset_n=>areset_n, |
stb_i=>outboundStb_i, |
dataM_i=>outboundDat_i, |
ack_o=>outboundAck_o, |
stb_o=>outboundStb, |
dataS_o=>outboundDat, |
ack_i=>outboundAck); |
|
Egress: RioLogicalCommonEgress |
port map( |
clk=>clk, areset_n=>areset_n, |
163,10 → 196,10
writeFrameAbort_o=>writeFrameAbort_o, |
writeContent_o=>writeContent_o, |
writeContentData_o=>writeContentData_o, |
slaveCyc_i=>slaveCyc_i, |
slaveStb_i=>slaveStb_i, |
slaveDat_i=>slaveDat_i, |
slaveAck_o=>slaveAck_o); |
outboundCyc_i=>'1', |
outboundStb_i=>outboundStb, |
outboundDat_i=>outboundDat, |
outboundAck_o=>outboundAck); |
|
end architecture; |
|
175,9 → 208,6
------------------------------------------------------------------------------- |
-- RioLogicalCommonIngress. |
------------------------------------------------------------------------------- |
-- REMARK: Check the destination address to see if it matches the one configured??? |
-- REMARK: Remove the acknowledge on all accesses on the master bus. |
-- REMARK: Add component declarations to riocommon.vhd. |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
197,11 → 227,11
readContentEnd_i : in std_logic; |
readContentData_i : in std_logic_vector(31 downto 0); |
|
masterCyc_o : out std_logic; |
masterStb_o : out std_logic; |
masterAdr_o : out std_logic_vector(7 downto 0); |
masterDat_o : out std_logic_vector(31 downto 0); |
masterAck_i : in std_logic); |
inboundCyc_o : out std_logic; |
inboundStb_o : out std_logic; |
inboundAdr_o : out std_logic_vector(7 downto 0); |
inboundDat_o : out std_logic_vector(31 downto 0); |
inboundAck_i : in std_logic); |
end entity; |
|
|
216,7 → 246,7
END_PACKET); |
signal state : StateType; |
|
signal packetPosition : natural range 0 to 32; |
signal packetPosition : natural range 0 to 68; |
signal packetContent : std_logic_vector(63 downto 0); |
|
signal tt : std_logic_vector(1 downto 0); |
240,10 → 270,10
readContent_o <= '0'; |
readFrame_o <= '0'; |
|
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
masterAdr_o <= (others=>'0'); |
masterDat_o <= (others=>'0'); |
inboundCyc_o <= '0'; |
inboundStb_o <= '0'; |
inboundAdr_o <= (others=>'0'); |
inboundDat_o <= (others=>'0'); |
elsif (clk'event and clk = '1') then |
readContent_o <= '0'; |
readFrame_o <= '0'; |
298,10 → 328,10
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
masterCyc_o <= '1'; |
masterStb_o <= '1'; |
masterAdr_o <= ftype & transaction; |
masterDat_o <= x"0000" & packetContent(63 downto 48); |
inboundCyc_o <= '1'; |
inboundStb_o <= '1'; |
inboundAdr_o <= ftype & transaction; |
inboundDat_o <= x"0000" & packetContent(63 downto 48); |
packetContent <= packetContent(47 downto 0) & x"0000"; |
|
state <= SEND_DESTINATION; |
310,12 → 340,12
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (inboundAck_i = '1') then |
if (tt = "00") then |
masterDat_o <= x"000000" & packetContent(63 downto 56); |
inboundDat_o <= x"000000" & packetContent(63 downto 56); |
packetContent <= packetContent(55 downto 0) & x"00"; |
elsif (tt = "01") then |
masterDat_o <= x"0000" & packetContent(63 downto 48); |
inboundDat_o <= x"0000" & packetContent(63 downto 48); |
packetContent <= packetContent(47 downto 0) & x"0000"; |
end if; |
|
326,12 → 356,12
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (inboundAck_i = '1') then |
if (tt = "00") then |
masterDat_o <= x"000000" & packetContent(63 downto 56); |
inboundDat_o <= x"000000" & packetContent(63 downto 56); |
packetContent <= packetContent(55 downto 0) & x"00"; |
elsif (tt = "01") then |
masterDat_o <= x"0000" & packetContent(63 downto 48); |
inboundDat_o <= x"0000" & packetContent(63 downto 48); |
packetContent <= packetContent(47 downto 32) & readContentData_i & x"0000"; |
readContent_o <= '1'; |
end if; |
343,19 → 373,19
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
if (inboundAck_i = '1') then |
packetPosition <= packetPosition + 1; |
|
if (tt = "00") then |
masterDat_o <= packetContent(63 downto 32); |
inboundDat_o <= packetContent(63 downto 32); |
packetContent <= packetContent(31 downto 0) & readContentData_i; |
elsif (tt = "01") then |
masterDat_o <= packetContent(63 downto 32); |
inboundDat_o <= packetContent(63 downto 32); |
packetContent <= packetContent(31 downto 16) & readContentData_i & x"0000"; |
end if; |
|
if (readContentEnd_i = '0') then |
if (packetPosition = 20) then |
if (packetPosition = 18) then |
state <= FORWARD_CRC; |
end if; |
|
370,12 → 400,12
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
masterDat_o <= packetContent(63 downto 32); |
if (inboundAck_i = '1') then |
inboundDat_o <= packetContent(63 downto 32); |
|
packetPosition <= packetPosition + 1; |
packetContent <= |
packetContent(31 downto 0) & readContentData_i(15 downto 0) & x"0000"; |
packetContent(31 downto 16) & readContentData_i(15 downto 0) & x"00000000"; |
|
if (readContentEnd_i = '0') then |
readContent_o <= '1'; |
390,12 → 420,12
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
masterDat_o <= packetContent(63 downto 32); |
if (inboundAck_i = '1') then |
inboundDat_o <= packetContent(63 downto 32); |
|
packetPosition <= packetPosition + 1; |
packetContent <= |
packetContent(15 downto 0) & readContentData_i & x"0000"; |
readContentData_i & x"00000000"; |
|
if (readContentEnd_i = '0') then |
readContent_o <= '1'; |
409,9 → 439,8
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
-- REMARK: The last always contain the CRC? |
if (masterAck_i = '1') then |
masterDat_o <= packetContent(63 downto 32); |
if (inboundAck_i = '1') then |
inboundDat_o <= packetContent(63 downto 32); |
state <= END_PACKET; |
end if; |
|
419,9 → 448,9
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if (masterAck_i = '1') then |
masterCyc_o <= '0'; |
masterStb_o <= '0'; |
if (inboundAck_i = '1') then |
inboundCyc_o <= '0'; |
inboundStb_o <= '0'; |
state <= IDLE; |
end if; |
|
464,10 → 493,10
writeContent_o : out std_logic; |
writeContentData_o : out std_logic_vector(31 downto 0); |
|
slaveCyc_i : in std_logic; |
slaveStb_i : in std_logic; |
slaveDat_i : in std_logic_vector(31 downto 0); |
slaveAck_o : out std_logic); |
outboundCyc_i : in std_logic; |
outboundStb_i : in std_logic; |
outboundDat_i : in std_logic_vector(31 downto 0); |
outboundAck_o : out std_logic); |
end entity; |
|
|
540,7 → 569,7
|
crcReset <= '0'; |
|
slaveAck_o <= '0'; |
outboundAck_o <= '0'; |
|
writeFrame_o <= '0'; |
writeFrameAbort_o <= '0'; |
565,11 → 594,11
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then |
temp <= slaveDat_i(15 downto 0); |
tt <= slaveDat_i(5 downto 4); |
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then |
temp <= outboundDat_i(15 downto 0); |
tt <= outboundDat_i(5 downto 4); |
|
slaveAck_o <= '1'; |
outboundAck_o <= '1'; |
state <= HEADER_ACK; |
else |
state <= HEADER_GET; |
579,7 → 608,7
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
slaveAck_o <= '0'; |
outboundAck_o <= '0'; |
state <= DESTINATION_GET; |
|
when DESTINATION_GET => |
587,14 → 616,14
-- |
--------------------------------------------------------------------- |
|
if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then |
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then |
if (tt = "01") then |
writeContentData2 <= temp & slaveDat_i(15 downto 0); |
writeContentData2 <= temp & outboundDat_i(15 downto 0); |
else |
report "TT-field not supported." severity error; |
end if; |
|
slaveAck_o <= '1'; |
outboundAck_o <= '1'; |
state <= DESTINATION_ACK; |
else |
state <= RESTART_FRAME; |
604,7 → 633,7
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
slaveAck_o <= '0'; |
outboundAck_o <= '0'; |
state <= SOURCE_GET; |
|
when SOURCE_GET => |
612,12 → 641,12
-- |
--------------------------------------------------------------------- |
|
if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then |
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then |
if (tt = "01") then |
temp <= slaveDat_i(15 downto 0); |
temp <= outboundDat_i(15 downto 0); |
end if; |
|
slaveAck_o <= '1'; |
outboundAck_o <= '1'; |
state <= SOURCE_ACK; |
else |
state <= RESTART_FRAME; |
627,7 → 656,7
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
slaveAck_o <= '0'; |
outboundAck_o <= '0'; |
state <= CONTENT_GET; |
|
when CONTENT_GET => |
634,12 → 663,12
--------------------------------------------------------------------- |
-- |
--------------------------------------------------------------------- |
if ((slaveCyc_i = '1') and (slaveStb_i = '1')) then |
if ((outboundCyc_i = '1') and (outboundStb_i = '1')) then |
if (packetPosition < 19) then |
if (tt = "01") then |
writeContentData2 <= temp & slaveDat_i(31 downto 16); |
temp <= slaveDat_i(15 downto 0); |
slaveAck_o <= '1'; |
writeContentData2 <= temp & outboundDat_i(31 downto 16); |
temp <= outboundDat_i(15 downto 0); |
outboundAck_o <= '1'; |
end if; |
elsif (packetPosition = 19) then |
if (tt = "01") then |
647,8 → 676,8
end if; |
else |
if (tt = "01") then |
writeContentData2 <= slaveDat_i; |
slaveAck_o <= '1'; |
writeContentData2 <= outboundDat_i; |
outboundAck_o <= '1'; |
end if; |
end if; |
writeContent <= '1'; |
668,7 → 697,7
writeContentData2 <= crc16Next & temp; |
end if; |
end if; |
slaveAck_o <= '0'; |
outboundAck_o <= '0'; |
state <= CONTENT_GET; |
|
when CRC_APPEND => |
765,3 → 794,81
d_i=>writeContentData1(15 downto 0), crc_i=>crc16Temp, crc_o=>crc16Next); |
|
end architecture; |
|
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.rio_common.all; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
entity RioLogicalCommonInterconnect is |
generic( |
WIDTH : natural); |
port( |
clk : in std_logic; |
areset_n : in std_logic; |
|
stb_i : in std_logic_vector(WIDTH-1 downto 0); |
dataM_i : in std_logic_vector(32*WIDTH-1 downto 0); |
ack_o : out std_logic_vector(WIDTH-1 downto 0); |
|
stb_o : out std_logic; |
dataS_o : out std_logic_vector(31 downto 0); |
ack_i : in std_logic); |
end entity; |
|
|
------------------------------------------------------------------------------- |
-- |
------------------------------------------------------------------------------- |
architecture RioLogicalCommonInterconnectImpl of RioLogicalCommonInterconnect is |
signal activeCycle : std_logic; |
signal selectedMaster : natural range 0 to WIDTH-1; |
begin |
|
----------------------------------------------------------------------------- |
-- Arbitration. |
----------------------------------------------------------------------------- |
Arbiter: process(areset_n, clk) |
begin |
if (areset_n = '0') then |
activeCycle <= '0'; |
selectedMaster <= 0; |
elsif (clk'event and clk = '1') then |
if (activeCycle = '0') then |
for i in 0 to WIDTH-1 loop |
if (stb_i(i) = '1') then |
activeCycle <= '1'; |
selectedMaster <= i; |
end if; |
end loop; |
else |
if (stb_i(selectedMaster) = '0') then |
activeCycle <= '0'; |
end if; |
end if; |
end if; |
end process; |
|
----------------------------------------------------------------------------- |
-- Interconnection. |
----------------------------------------------------------------------------- |
stb_o <= stb_i(selectedMaster) and activeCycle; |
dataS_o <= dataM_i(32*(selectedMaster+1)-1 downto 32*selectedMaster); |
|
Interconnect: for i in 0 to WIDTH-1 generate |
ack_o(i) <= ack_i when (selectedMaster = i) else '0'; |
end generate; |
|
end architecture; |
|
|