From 012ddb6bafede4cd3ea96167bac7e2ef284a65da Mon Sep 17 00:00:00 2001 From: Richard Huber Date: Wed, 28 Mar 2012 23:06:17 +0200 Subject: [PATCH] Added full switch source to noc_switch IP --- .../endOfPacket/endOfPacketDetector.vhd | 19 ++ .../hdl/vhdl/switch/header/headerDecoder.vhd | 23 +++ .../hdl/vhdl/switch/header/headerDetector.vhd | 64 ++++++ .../vhdl/switch/router/extTxPortSelect.vhd | 63 ++++++ .../hdl/vhdl/switch/router/headerFetch.vhd | 65 ++++++ .../hdl/vhdl/switch/router/headerSelect.vhd | 74 +++++++ .../vhdl/switch/router/intTxPortSelect.vhd | 46 +++++ .../hdl/vhdl/switch/router/router.vhd | 195 ++++++++++++++++++ .../hdl/vhdl/switch/router/rxPort.vhd | 54 +++++ .../hdl/vhdl/switch/router/txFifo.vhd | 90 ++++++++ .../hdl/vhdl/switch/router/txFifoSelect.vhd | 39 ++++ .../hdl/vhdl/switch/router/txPort.vhd | 67 ++++++ .../hdl/vhdl/switch/switch.vhd | 132 ++++++++++++ 13 files changed, 931 insertions(+) create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/endOfPacket/endOfPacketDetector.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDecoder.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDetector.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/extTxPortSelect.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerFetch.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerSelect.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/intTxPortSelect.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/router.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/rxPort.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifo.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifoSelect.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txPort.vhd create mode 100644 pcores/noc_switch_v1_00_a/hdl/vhdl/switch/switch.vhd diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/endOfPacket/endOfPacketDetector.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/endOfPacket/endOfPacketDetector.vhd new file mode 100644 index 0000000..c5d4e76 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/endOfPacket/endOfPacketDetector.vhd @@ -0,0 +1,19 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity endOfPacketDetector is + port ( + dataValid : in std_logic; + flag : in std_logic; + fifoEnable : in std_logic; + + endOfPacket : out std_logic + ); +end entity endOfPacketDetector; + +architecture rtl of endOfPacketDetector is +begin + + endOfPacket <= dataValid and fifoEnable and flag; + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDecoder.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDecoder.vhd new file mode 100644 index 0000000..51ecf97 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDecoder.vhd @@ -0,0 +1,23 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.headerPkg.all; + +entity headerDecoder is + port ( + data : in std_logic_vector(dataWidth-1 downto 0); + + destAddr : out address; + prio : out priority + ); +end entity headerDecoder; + +architecture rtl of headerDecoder is + +begin + + destAddr <= extractAddress(data); + prio <= extractPrio(data); + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDetector.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDetector.vhd new file mode 100644 index 0000000..851ee12 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/header/headerDetector.vhd @@ -0,0 +1,64 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity headerDetector is + port ( + clk : in std_logic; + reset : in std_logic; + + readEnable : in std_logic; + empty : in std_logic; + endOfPacket : in std_logic; + + headerValid : out std_logic + ); +end entity headerDetector; + +architecture rtl of headerDetector is + + type state is (idle, packetTransfer); + signal state_p, state_n : state; + +begin + + nomem_output : process (state_p, readEnable, empty, endOfPacket) is + begin + -- default assignment + headerValid <= '0'; + + if state_p = idle then + headerValid <= not empty; + end if; + + end process nomem_output; + + nomem_nextState : process(state_p, empty, readEnable, endOfPacket) is + begin + -- default assignment + state_n <= state_p; + + case state_p is + when idle => + if empty='0' and readEnable='1' then + state_n <= packetTransfer; + end if; + when packetTransfer => + if endOfPacket='1' and readEnable='1' then + state_n <= idle; + end if; + end case; + + end process nomem_nextState; + + mem_stateTransition : process (clk, reset) is + begin + if reset = '0' then + state_p <= idle; + elsif rising_edge(clk) then + state_p <= state_n; + end if; + end process mem_stateTransition; + + + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/extTxPortSelect.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/extTxPortSelect.vhd new file mode 100644 index 0000000..c23a50f --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/extTxPortSelect.vhd @@ -0,0 +1,63 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.switchPkg.all; + +entity extTxPortSelect is + port ( + rxPortNrIn : in portNr; + rxPortNrOut : out portNr; + + txPortIdle : in std_logic_vector(numExtPorts-1 downto 0); + txPortWriteEnable : out std_logic_vector(numExtPorts-1 downto 0); + + txFifoReadEnable : out std_logic; + txFifoEmpty : in std_logic; + + txPortNrOut : out portNr; + rxPortWriteEnable : out std_logic_vector(numPorts-1 downto 0) + ); +end entity extTxPortSelect; + +architecture rtl of extTxPortSelect is + + function selectTxPort(txPortIdle: std_logic_vector(numExtPorts-1 downto 0)) return portNrWrapper is + variable result : portNrWrapper; + begin + result := (others => '0'); + while result < numExtPorts loop + if txPortIdle(wrappedPortNrToInteger(result)) = '1' then + return result + numIntPorts; + end if; + result := result + 1; + end loop; + return result + numIntPorts; + end selectTxPort; + +begin + + rxPortNrOut <= rxPortNrIn; + + nomem_output:process(txPortIdle, txFifoEmpty, rxPortNrIn) is + variable txPortNr : portNrWrapper; + begin + -- default assignments + txPortWriteEnable <= (others => '0'); + txFifoReadEnable <= '0'; + rxPortWriteEnable <= (others => '0'); + txPortNrOut <= (others => '-'); + + if txFifoEmpty = '0' then + txPortNr := selectTxPort(txPortIdle); + if txPortNr /= portNrUndefined then + txPortWriteEnable(wrappedPortNrToInteger(txPortNr-numIntPorts)) <= '1'; + txFifoReadEnable <= '1'; + txPortNrOut <= txPortNr; + rxPortWriteEnable(portNrToInteger(rxPortNrIn)) <= '1'; + end if; + end if; + + end process nomem_output; + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerFetch.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerFetch.vhd new file mode 100644 index 0000000..6c8f095 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerFetch.vhd @@ -0,0 +1,65 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.headerPkg.all; + +entity headerFetch is + port ( + clk : in std_logic; + reset : in std_logic; + + headerIn : in header; + endOfRxPacket : in std_logic; + selected : in std_logic; + + headerOut : out header + ); +end entity headerFetch; + +architecture rtl of headerFetch is + + type state is (idle, packetTransfer); + signal state_p, state_n : state; + +begin + + nomem_output : process (state_p, headerIn) is + begin + -- default assignment + headerOut <= headerIn; + + if state_p=packetTransfer then + headerOut.valid <= '0'; + end if; + + end process nomem_output; + + nomem_nextState : process (state_p, selected, endOfRxPacket) is + begin + -- default assignment + state_n <= state_p; + + case state_p is + when idle => + if selected='1' then + state_n <= packetTransfer; + end if; + when packetTransfer => + if endOfRxPacket='1' then + state_n <= idle; + end if; + end case; + end process nomem_nextState; + + + mem_stateTransition : process (clk, reset) is + begin + if reset = '0' then + state_p <= idle; + elsif rising_edge(clk) then + state_p <= state_n; + end if; + end process mem_stateTransition; + + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerSelect.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerSelect.vhd new file mode 100644 index 0000000..0327108 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/headerSelect.vhd @@ -0,0 +1,74 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.headerPkg.all; +use work.utilPkg.all; +use work.switchPkg.all; + +entity headerSelect is + port ( + headerIn : in headerArray(numPorts-1 downto 0); + selected : out std_logic_vector(numPorts-1 downto 0); + + dataValid : out std_logic; + selectedRxPort : out portNr; + selectedAddr : out address + ); +end entity headerSelect; + + +architecture rtl of headerSelect is + + function selectHeaderWithPrio(headers:headerArray(numPorts-1 downto 0); searchedPrio:priority) return portNrWrapper is + variable rxPortNr : portNrWrapper; + begin + rxPortNr := (others => '0'); + while rxPortNr '0'); + dataValid <= '0'; + selectedRxPort <= (others => '-'); + selectedAddr <= dontCareAddr; + + rxPortNr := selectHeader(headerIn); + if rxPortNr /= portNrUndefined then + selected(wrappedPortNrToInteger(rxPortNr)) <= '1'; + dataValid <= '1'; + selectedRxPort <= toPortNr(rxPortNr); + selectedAddr <= headerIn(wrappedPortNrToInteger(rxPortNr)).addr; + end if; + + end process nomem_output; +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/intTxPortSelect.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/intTxPortSelect.vhd new file mode 100644 index 0000000..98a3063 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/intTxPortSelect.vhd @@ -0,0 +1,46 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.switchPkg.all; + +entity intTxPortSelect is + generic( + txPortNr : portNr + ); + port ( + rxPortNrIn : in portNr; + rxPortNrOut : out portNr; + + txPortIdle : in std_logic; + txPortWriteEnable : out std_logic; + + txFifoReadEnable : out std_logic; + txFifoEmpty : in std_logic; + + txPortNrOut : out portNr; + rxPortWriteEnable : out std_logic_vector(numPorts-1 downto 0) + ); +end entity intTxPortSelect; + +architecture rtl of intTxPortSelect is + +begin + + txPortNrOut <= txPortNr; + rxPortNrOut <= rxPortNrIn; + + nomem_output:process(txPortIdle, txFifoEmpty, rxPortNrIn) is + begin + -- default assignments + txPortWriteEnable <= '0'; + txFifoReadEnable <= '0'; + rxPortWriteEnable <= (others => '0'); + + if txPortIdle = '1' and txFifoEmpty = '0' then + txPortWriteEnable <= '1'; + txFifoReadEnable <= '1'; + rxPortWriteEnable(portNrToInteger(rxPortNrIn)) <= '1'; + end if; + end process nomem_output; + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/router.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/router.vhd new file mode 100644 index 0000000..955626a --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/router.vhd @@ -0,0 +1,195 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.headerPkg.all; +use work.switchPkg.all; + +entity router is + generic( + globalAddress : globalAddr + ); + port ( + clk : in std_logic; + reset : in std_logic; + + routingRequest : in headerArray(numPorts-1 downto 0); + endOfRxPacket : in std_logic_vector(numPorts-1 downto 0); + endOfTxPacket : in std_logic_vector(numPorts-1 downto 0); + + txPortMap : out portNrWrapperArray(numPorts-1 downto 0); + rxPortMap : out portNrWrapperArray(numPorts-1 downto 0) + ); +end entity router; + +architecture structural of router is + + signal headerFetch_headerOut : headerArray(numPorts-1 downto 0); + signal headerFetch_selected : std_logic_vector(numPorts-1 downto 0); + + signal headerSelect_dataValid : std_logic; + signal headerSelect_selectedRxPort : portNr; + signal headerSelect_selectedAddr : address; + + signal txFifoSelect_txFifoWriteEnable : std_logic_vector(numIntPorts downto 0); + + signal txFifo_ReadEnable : std_logic_vector(numIntPorts downto 0); + signal txFifo_empty : std_logic_vector(numIntPorts downto 0); + signal txFifo_rxPortNr : portNrArray(numIntPorts downto 0); + + signal intTxPortSelect_idle : std_logic_vector(numIntPorts-1 downto 0); + signal intTxPortSelect_txPortWriteEnable: std_logic_vector(numIntPorts-1 downto 0); + + signal txPortSelect_rxPortNr : portNrArray(numIntPorts downto 0); + signal txPortSelect_txPortNr : portNrArray(numIntPorts downto 0); + type txPortSelect_rxPortWriteEnable_type is array(numIntPorts downto 0) of std_logic_vector(numPorts-1 downto 0); + signal txPortSelect_rxPortWriteEnable : txPortSelect_rxPortWriteEnable_type; + + signal extTxPortSelect_idle : std_logic_vector(numExtPorts-1 downto 0); + signal extTxPortSelect_txPortWriteEnable: std_logic_vector(numExtPorts-1 downto 0); + + type rxPort_writeEnable_type is array(numPorts-1 downto 0) of std_logic_vector(numIntPorts downto 0); + signal rxPort_writeEnable : rxPort_writeEnable_type; + +begin + + headerFetchGenerate : for i in numPorts-1 downto 0 generate + + headerFetchEntity: entity work.headerFetch + port map ( + clk => clk, + reset => reset, + headerIn => routingRequest(i), + endOfRxPacket => endOfRxPacket(i), + selected => headerFetch_selected(i), + headerOut => headerFetch_headerOut(i) + ); + + end generate headerFetchGenerate; + + headerSelectEntity: entity work.headerSelect + port map ( + headerIn => headerFetch_headerOut, + selected => headerFetch_selected, + dataValid => headerSelect_dataValid, + selectedRxPort => headerSelect_selectedRxPort, + selectedAddr => headerSelect_selectedAddr + ); + + txFifoSelectEntity: entity work.txFifoSelect + generic map ( + globalAddress => globalAddress + ) + port map ( + selectedAddr => headerSelect_selectedAddr, + dataValid => headerSelect_dataValid, + fifoWriteEnable => txFifoSelect_txFifoWriteEnable + ); + + intTxFifoGenerate: for i in numIntPorts-1 downto 0 generate + + intTxFifoEntity: entity work.txFifo + port map ( + clk => clk, + reset => reset, + writeEnable => txFifoSelect_txFifoWriteEnable(i), + readEnable => txFifo_readEnable(i), + empty => txFifo_empty(i), + rxPortNrIn => headerSelect_selectedRxPort, + rxPortNrOut => txFifo_rxPortNr(i) + ); + + end generate intTxFifoGenerate; + + extTxFifoEntity: entity work.txFifo + port map ( + clk => clk, + reset => reset, + writeEnable => txFifoSelect_txFifoWriteEnable(numIntPorts), + readEnable => txFifo_readEnable(numIntPorts), + empty => txFifo_empty(numIntPorts), + rxPortNrIn => headerSelect_selectedRxPort, + rxPortNrOut => txFifo_rxPortNr(numIntPorts) + ); + + intTxPortSelectGenerate: for i in numIntPorts-1 downto 0 generate + + intTxPortSelectEntity: entity work.intTxPortSelect + generic map ( + txPortNr => integerToPortNr(i) + ) + port map ( + rxPortNrIn => txFifo_rxPortNr(i), + rxPortNrOut => txPortSelect_rxPortNr(i), + txPortIdle => intTxPortSelect_idle(i), + txPortWriteEnable => intTxPortSelect_txPortWriteEnable(i), + txFifoReadEnable => txFifo_ReadEnable(i), + txFifoEmpty => txFifo_empty(i), + txPortNrOut => txPortSelect_txPortNr(i), + rxPortWriteEnable => txPortSelect_rxPortWriteEnable(i) + ); + + end generate intTxPortSelectGenerate; + + extTxPortSelectEntity: entity work.extTxPortSelect + port map ( + rxPortNrIn => txFifo_rxPortNr(numIntPorts), + rxPortNrOut => txPortSelect_rxPortNr(numIntPorts), + txPortIdle => extTxPortSelect_idle, + txPortWriteEnable => extTxPortSelect_txPortWriteEnable, + txFifoReadEnable => txFifo_ReadEnable(numIntPorts), + txFifoEmpty => txFifo_empty(numIntPorts), + txPortNrOut => txPortSelect_txPortNr(numIntPorts), + rxPortWriteEnable => txPortSelect_rxPortWriteEnable(numIntPorts) + ); + + intTxPortGenerate: for i in numIntPorts-1 downto 0 generate + + intTxPortEntity: entity work.txPort + port map( + clk => clk, + reset => reset, + rxPortNrIn => txPortSelect_rxPortNr(i), + rxPortNrOut => txPortMap(i), + idle => intTxPortSelect_idle(i), + writeEnable => intTxPortSelect_txPortWriteEnable(i), + endOfPacket => endOfTxPacket(i) + ); + + end generate intTxPortGenerate; + + extTxPortGenerate: for i in numExtPorts-1 downto 0 generate + + extTxPortEntity: entity work.txPort + port map( + clk => clk, + reset => reset, + rxPortNrIn => txPortSelect_rxPortNr(numIntPorts), + rxPortNrOut => txPortMap(numIntPorts + i), + idle => extTxPortSelect_idle(i), + writeEnable => extTxPortSelect_txPortWriteEnable(i), + endOfPacket => endOfTxPacket(numIntPorts + i) + ); + + end generate extTxPortGenerate; + + rxPortGenerate: for i in numPorts-1 downto 0 generate + + rxPortEntity:entity work.rxPort + port map( + clk => clk, + reset => reset, + txPortNrIn => txPortSelect_txPortNr, + txPortNrOut => rxPortMap(i), + writeEnable => rxPort_writeEnable(i), + endOfPacket => endOfRxPacket(i) + ); + + end generate rxPortGenerate; + + rxPortWriteEnableMappingGenerate: for i in numPorts-1 downto 0 generate + j: for j in numIntPorts downto 0 generate + rxPort_writeEnable(i)(j) <= txPortSelect_rxPortWriteEnable(j)(i); + end generate j; + end generate rxPortWriteEnableMappingGenerate; + +end architecture structural; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/rxPort.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/rxPort.vhd new file mode 100644 index 0000000..d1efef2 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/rxPort.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.switchPkg.all; + +entity rxPort is + port ( + clk : in std_logic; + reset : in std_logic; + + txPortNrIn : in portNrArray(numIntPorts downto 0); + txPortNrOut : out portNrWrapper; + + writeEnable : in std_logic_vector(numIntPorts downto 0); + endOfPacket : in std_logic + ); +end entity rxPort; + +architecture rtl of rxPort is + + signal txPortNr_p, txPortNr_n : portNrWrapper; + +begin + + txPortNrOut <= txPortNr_p; + + nomem_nextState : process(txPortNr_p, writeEnable, txPortNrIn, endOfPacket) is + begin + -- default assignments + txPortNr_n <= txPortNr_p; + + for i in numIntPorts downto 0 loop + if writeEnable(i)='1' then + txPortNr_n <= toPortNrWrapper(txPortNrIn(i)); + exit; + end if; + end loop; + + if endOfPacket='1' then + txPortNr_n <= portNrUndefined; + end if; + end process nomem_nextState; + + mem_stateTransition : process(clk, reset) is + begin + if reset = '0' then + txPortNr_p <= portNrUndefined; + elsif rising_edge(clk) then + txPortNr_p <= txPortNr_n; + end if; + end process mem_stateTransition; + + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifo.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifo.vhd new file mode 100644 index 0000000..33f06f2 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifo.vhd @@ -0,0 +1,90 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.utilPkg.all; +use work.headerPkg.all; +use work.switchPkg.all; + +entity txFifo is + port ( + clk : in std_logic; + reset : in std_logic; + + writeEnable : in std_logic; + readEnable : in std_logic; + empty : out std_logic; + + rxPortNrIn : in portNr; + rxPortNrOut : out portNr + ); +end entity txFifo; + +architecture rtl of txFifo is + + subtype position is unsigned(toLog2Ceil(numPorts)-1 downto 0); + subtype positionInteger is integer range numPorts-1 downto 0; + function positionToInteger(pos: position) return positionInteger is + variable result : positionInteger; + begin + result := to_integer(pos); + return result; + end function positionToInteger; + + signal readPosition_p, readPosition_n, writePosition_p, writePosition_n : position; + + signal ringBuffer_p, ringBuffer_n : portNrArray(numPorts-1 downto 0); + +begin + + rxPortNrOut <= ringBuffer_p(positionToInteger(readPosition_p)); + + nomem_output : process(readPosition_p, writePosition_p) is + begin + empty <= '0'; + if readPosition_p = writePosition_p then + empty <= '1'; + end if; + end process nomem_output; + + nomem_nextState : process(readPosition_p, writePosition_p, ringBuffer_p, writeEnable, readEnable, rxPortNrIn) is + begin + -- default assignments + readPosition_n <= readPosition_p; + writePosition_n <= writePosition_p; + ringBuffer_n <= ringBuffer_p; + + -- writing + if writeEnable = '1' then + ringBuffer_n(positionToInteger(writePosition_p)) <= rxPortNrIn; + if writePosition_p < numPorts-1 then + writePosition_n <= writePosition_p + 1; + else + writePosition_n <= (others => '0'); + end if; + end if; + + -- reading + if readEnable = '1' then + if readPosition_p < numPorts-1 then + readPosition_n <= readPosition_p + 1; + else + readPosition_n <= (others => '0'); + end if; + end if; + end process nomem_nextState; + + mem_stateTransition : process (clk, reset) is + begin + if reset = '0' then + readPosition_p <= (others => '0'); + writePosition_p <= (others => '0'); + elsif rising_edge(clk) then + readPosition_p <= readPosition_n; + writePosition_p <= writePosition_n; + ringBuffer_p <= ringBuffer_n; + end if; + end process mem_stateTransition; + + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifoSelect.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifoSelect.vhd new file mode 100644 index 0000000..bc33e67 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txFifoSelect.vhd @@ -0,0 +1,39 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.utilPkg.all; +use work.headerPkg.all; +use work.switchPkg.all; + +entity txFifoSelect is + generic( + globalAddress : globalAddr + ); + port ( + selectedAddr : in address; + dataValid : in std_logic; + + fifoWriteEnable : out std_logic_vector(numIntPorts downto 0) -- one for each internal fifo and one for the global fifo + ); +end entity txFifoSelect; + +architecture rtl of txFifoSelect is +begin + + nomem_output : process (selectedAddr, dataValid) is + begin + -- default assignment + fifoWriteEnable <= (others => '0'); + + if dataValid = '1' then + -- second condition required because of possible inconsistent transient state + if selectedAddr.global = globalAddress and unsigned(selectedAddr.local) < numIntPorts then + fifoWriteEnable(localAddrToInteger(selectedAddr.local)) <= '1'; + else + fifoWriteEnable(numIntPorts) <= '1'; + end if; + end if; + end process nomem_output; + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txPort.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txPort.vhd new file mode 100644 index 0000000..9e9f382 --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/router/txPort.vhd @@ -0,0 +1,67 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.switchPkg.all; + +entity txPort is + port ( + clk : in std_logic; + reset : in std_logic; + + rxPortNrIn : in portNr; + rxPortNrOut : out portNrWrapper; + + idle : out std_logic; + writeEnable : in std_logic; + endOfPacket : in std_logic + ); +end entity txPort; + +architecture rtl of txPort is + + type state is (idleState, packetTransfer); + signal state_p, state_n : state; + + signal rxPortNr_p, rxPortNr_n : portNrWrapper; + +begin + + rxPortNrOut <= rxPortNr_p; + + nomem_output:process(state_p) is + begin + idle <= '0'; + if state_p=idleState then + idle <= '1'; + end if; + end process nomem_output; + + nomem_nextState : process(state_p, rxPortNr_p, writeEnable, rxPortNrIn, endOfPacket) is + begin + -- default assignments + state_n <= state_p; + rxPortNr_n <= rxPortNr_p; + + if writeEnable = '1' then + state_n <= packetTransfer; + rxPortNr_n <= toPortNrWrapper(rxPortNrIn); + end if; + if endOfPacket='1' then + state_n <= idleState; + rxPortNr_n <= portNrUndefined; + end if; + end process nomem_nextState; + + mem_stateTransition : process(clk, reset) is + begin + if reset = '0' then + state_p <= idleState; + rxPortNr_p <= portNrUndefined; + elsif rising_edge(clk) then + state_p <= state_n; + rxPortNr_p <= rxPortNr_n; + end if; + end process mem_stateTransition; + + +end architecture rtl; diff --git a/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/switch.vhd b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/switch.vhd new file mode 100644 index 0000000..080c31c --- /dev/null +++ b/pcores/noc_switch_v1_00_a/hdl/vhdl/switch/switch.vhd @@ -0,0 +1,132 @@ +library ieee; +use ieee.std_logic_1164.all; + +use work.switchPkg.all; +use work.headerPkg.all; + +entity switch is + generic( + globalAddress : globalAddr -- The global address of this switch. Packets with this global address are forwarded to the internal output link corresponding to the local address of the packet. + ); + port ( + clk : in std_logic; + reset : in std_logic; + inputLinksIn : in inputLinkInArray(numPorts-1 downto 0); -- Input signals of the input links (internal AND external links) + inputLinksOut : out inputLinkOutArray(numPorts-1 downto 0); -- Output signals of the input links (internal AND external links) + outputLinksIn : in outputLinkInArray(numPorts-1 downto 0); -- Input signals of the output links (internal AND external links) + outputLinksOut : out outputLinkOutArray(numPorts-1 downto 0) -- Output signals of the output links (internal AND external) + ); +end entity switch; + +architecture structural of switch is + + constant defaultInputLinkInValue : inputLinkIn := (empty => '1', + data => (others => '-')); + constant defaultOutputLinkInValue : outputLinkIn := (full => '1'); + + signal inputLinksOutMuxOutput : inputLinkOutArray(numPorts-1 downto 0); + signal outputLinksOutMuxOutput : outputLinkOutArray(numPorts-1 downto 0); + + signal router_routingRequest : headerArray(numPorts-1 downto 0); + signal router_endOfRxPacket : std_logic_vector(numPorts-1 downto 0); + signal router_endOfTxPacket : std_logic_vector(numPorts-1 downto 0); + signal router_rxPortMap : portNrWrapperArray(numPorts-1 downto 0); + signal router_txPortMap : portNrWrapperArray(numPorts-1 downto 0); + + signal invertedOutputLinksInFull : std_logic_vector(numPorts-1 downto 0); + signal invertedInputLinksInEmpty : std_logic_vector(numPorts-1 downto 0); + +begin + + headerDetectorGenerate: for i in numPorts-1 downto 0 generate + + headerDetectorEntity : entity work.headerDetector + port map( + clk => clk, + reset => reset, + readEnable => inputLinksOutMuxOutput(i).readEnable, + empty => inputLinksIn(i).empty, + endOfPacket => inputLinksIn(i).data(dataWidth), + headerValid => router_routingRequest(i).valid + ); + + end generate headerDetectorGenerate; + + headerDecoderGenerate: for i in numPorts-1 downto 0 generate + + headerDecoderEntity : entity work.headerDecoder + port map( + data => inputLinksIn(i).data(dataWidth-1 downto 0), + destAddr => router_routingRequest(i).addr, + prio => router_routingRequest(i).prio + ); + + end generate headerDecoderGenerate; + + endOfPacketDetectorGenerate: for i in numPorts-1 downto 0 generate + + invertedInputLinksInEmpty(i) <= not inputLinksIn(i).empty; + + rxEndOfPacketDetectorEntity: entity work.endOfPacketDetector + port map( + dataValid => invertedInputLinksInEmpty(i), + flag => inputLinksIn(i).data(dataWidth), + fifoEnable => inputLinksOutMuxOutput(i).readEnable, + endOfPacket => router_endOfRxPacket(i) + ); + + invertedOutputLinksInFull(i) <= not outputLinksIn(i).full; + + txEndOfPacketDetectorEntity: entity work.endOfPacketDetector + port map( + dataValid => invertedOutputLinksInFull(i), + flag => outputLinksOutMuxOutput(i).data(dataWidth), + fifoEnable => outputLinksOutMuxOutput(i).writeEnable, + endOfPacket => router_endOfTxPacket(i) + ); + + end generate endOfPacketDetectorGenerate; + + routerEntity: entity work.router + generic map ( + globalAddress => globalAddress + ) + port map ( + clk => clk, + reset => reset, + routingRequest => router_routingRequest, + endOfRxPacket => router_endOfRxPacket, + endOfTxPacket => router_endOfTxPacket, + txPortMap => router_txPortMap, + rxPortMap => router_rxPortMap + ); + + nomem_inputMux: process(router_rxPortMap, outputLinksIn) is + variable muxOutput : outputLinkIn; + begin + for i in numPorts-1 downto 0 loop + muxOutput := defaultOutputLinkInValue; + if wrappedPortNrEqual(router_rxPortMap(i),portNrUndefined) = false then + muxOutput := outputLinksIn(wrappedPortNrToInteger(router_rxPortMap(i))); + end if; + inputLinksOutMuxOutput(i).readEnable <= not muxOutput.full; + end loop; + end process nomem_inputMux; + + nomem_outputMux: process(inputLinksIn, router_txPortMap) is + variable muxOutput : inputLinkIn; + begin + for i in numPorts-1 downto 0 loop + muxOutput := defaultInputLinkInValue; + if wrappedPortNrEqual(router_txPortMap(i),portNrUndefined) = false then + muxOutput := inputLinksIn(wrappedPortNrToInteger(router_txPortMap(i))); + end if; + outputLinksOutMuxOutput(i).data <= muxOutput.data; + outputLinksOutMuxOutput(i).writeEnable <= not muxOutput.empty; + end loop; + end process nomem_outputMux; + + inputLinksOut <= inputLinksOutMuxOutput; + outputLinksOut <= outputLinksOutMuxOutput; + +end architecture structural;