Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions intel/mii_gmii_io.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
-- This file is part of the ethernet_mac project.
--
-- For the full copyright and license information, please read the
-- LICENSE.md file that was distributed with this source code.
--
-- Device-specific IO setup needed for communicating with the PHY
--
-- Copyright (c) 2015, Philipp Kerling
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- * Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
--
-- * Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
--
-- * Neither the name of ethernet\_mac nor the names of its
-- contributors may be used to endorse or promote products derived from
-- this software without specific prior written permission.
--
-- * Neither the source code, nor any derivative product, may be used for military
-- purposes.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--

library ieee;
use ieee.std_logic_1164.all;

use work.ethernet_types.all;

entity mii_gmii_io is
port(
-- 125 MHz clock input (exact requirements can vary by implementation)
-- Spartan 6: clock should be unbuffered
clock_125_i : in std_ulogic;

-- RX and TX clocks
clock_tx_o : out std_ulogic;
clock_rx_o : out std_ulogic;

-- Speed selection for clock switch
speed_select_i : in t_ethernet_speed;

-- Signals connected directly to external ports
-- MII
mii_tx_clk_i : in std_ulogic;
mii_tx_en_o : out std_ulogic;
mii_txd_o : out t_ethernet_data;
mii_rx_clk_i : in std_ulogic;
mii_rx_er_i : in std_ulogic;
mii_rx_dv_i : in std_ulogic;
mii_rxd_i : in t_ethernet_data;

-- GMII
gmii_gtx_clk_o : out std_ulogic;

-- Signals connected to the mii_gmii module
int_mii_tx_en_i : in std_ulogic;
int_mii_txd_i : in t_ethernet_data;
int_mii_rx_er_o : out std_ulogic;
int_mii_rx_dv_o : out std_ulogic;
int_mii_rxd_o : out t_ethernet_data
);
end entity;

architecture Behavioral of mii_gmii_io is
signal clock_tx : std_ulogic := '0';
signal clock_rx : std_ulogic := '0';
begin
-- set tx-clock: switch between 125 Mhz reference clock and MII_TX_CLK for TX process
with speed_select_i select clock_tx <=
clock_125_i when SPEED_1000MBPS,
mii_tx_clk_i when others;
-- set rx-clock
clock_rx <= mii_rx_clk_i;

-- output 1000Mbps-clock only when running GMII to reduce switching noise
with speed_select_i select gmii_gtx_clk_o <=
clock_tx when SPEED_1000MBPS,
'0' when others;

-- output rx/tx-clocks
clock_tx_o <= clock_tx;
clock_rx_o <= clock_rx;

process (clock_tx)
begin
if rising_edge(clock_tx) then
-- output data to PHY
mii_tx_en_o <= int_mii_tx_en_i;
mii_txd_o <= int_mii_txd_i;
end if;
end process;

process (clock_rx)
begin
if rising_edge(clock_rx) then
-- receive data from PHY
int_mii_rx_dv_o <= mii_rx_dv_i;
int_mii_rx_er_o <= mii_rx_er_i;
int_mii_rxd_o <= mii_rxd_i;
end if;
end process;
end architecture;
68 changes: 68 additions & 0 deletions intel/single_signal_synchronizer.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
-- This file is part of the ethernet_mac project.
--
-- For the full copyright and license information, please read the
-- LICENSE.md file that was distributed with this source code.

-- Synchronize a single bit from an arbitrary clock domain
-- into the clock_target domain
--
-- Copyright (c) 2015, Philipp Kerling
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- * Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
--
-- * Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
--
-- * Neither the name of ethernet\_mac nor the names of its
-- contributors may be used to endorse or promote products derived from
-- this software without specific prior written permission.
--
-- * Neither the source code, nor any derivative product, may be used for military
-- purposes.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
library ieee;
use ieee.std_logic_1164.all;

entity single_signal_synchronizer is
port(
clock_target_i : in std_ulogic;
-- Asynchronous preset of the output and synchronizer flip-flops
preset_i : in std_ulogic := '0';
-- Asynchronous signal input
signal_i : in std_ulogic;
-- Synchronous signal output
signal_o : out std_ulogic
);
end entity;

architecture simple of single_signal_synchronizer is
signal signal_tmp : std_ulogic := '0';
begin
process(clock_target_i, preset_i)
begin
if preset_i = '1' then
signal_tmp <= '1';
signal_o <= '1';
elsif rising_edge(clock_target_i) then
signal_tmp <= signal_i;
signal_o <= signal_tmp;
end if;
end process;
end architecture;
120 changes: 120 additions & 0 deletions intel/utility.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
-- This file is part of the ethernet_mac project.
--
-- For the full copyright and license information, please read the
-- LICENSE.md file that was distributed with this source code.

-- Utility functions
--
-- Copyright (c) 2015, Philipp Kerling
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- * Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
--
-- * Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
--
-- * Neither the name of ethernet\_mac nor the names of its
-- contributors may be used to endorse or promote products derived from
-- this software without specific prior written permission.
--
-- * Neither the source code, nor any derivative product, may be used for military
-- purposes.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
library ieee;
use ieee.std_logic_1164.all;

package utility is
-- Return the reverse of the given vector
function reverse_vector(vec : in std_ulogic_vector) return std_ulogic_vector;
-- Return a vector with the bytes in opposite order but the content of the bytes unchanged (e.g. for big/little endian conversion)
function reverse_bytes(vec : in std_ulogic_vector) return std_ulogic_vector;
-- Extract a byte out of a vector
function extract_byte(vec : in std_ulogic_vector; byteno : in natural) return std_ulogic_vector;
-- Set a byte in a vector
procedure set_byte(vec : inout std_ulogic_vector; byteno : in natural; value : in std_ulogic_vector(7 downto 0));
end package;

package body utility is
function reverse_vector(vec : in std_ulogic_vector) return std_ulogic_vector is
variable result : std_ulogic_vector(vec'range);
alias rev_vec : std_ulogic_vector(vec'reverse_range) is vec;
begin
for i in rev_vec'range loop
result(i) := rev_vec(i);
end loop;
return result;
end function;

function reverse_bytes(vec : in std_ulogic_vector) return std_ulogic_vector is
variable result : std_ulogic_vector(vec'range);
begin
assert vec'length mod 8 = 0 report "Vector length must be a multiple of 8 for byte reversal" severity failure;
assert vec'low = 0 report "Vector must start at 0 for byte reversal" severity failure;
for byte in 0 to vec'high / 8 loop
set_byte(result, vec'high / 8 - byte, extract_byte(vec, byte));
end loop;
return result;
end function;

function extract_byte(vec : in std_ulogic_vector; byteno : in natural) return std_ulogic_vector is
begin
-- Support both vector directions
if vec'ascending then
--return vec(byteno * 8 to (byteno + 1) * 8 - 1); -- quartus cannot synthesize this
if (byteno = 0) then
return vec(0 to 7);
elsif (byteno = 1) then
return vec(8 to 15);
elsif (byteno = 2) then
return vec(16 to 23);
elsif (byteno = 3) then
return vec(24 to 31);
elsif (byteno = 4) then
return vec(32 to 39);
else
return vec(40 to 47);
end if;
else
--return vec((byteno + 1) * 8 - 1 downto byteno * 8); -- quartus cannot synthesize this
if (byteno = 0) then
return vec(7 downto 0);
elsif (byteno = 1) then
return vec(15 downto 8);
elsif (byteno = 2) then
return vec(23 downto 16);
elsif (byteno = 3) then
return vec(31 downto 24);
elsif (byteno = 4) then
return vec(39 downto 32);
else
return vec(47 downto 40);
end if;
end if;
end function;

procedure set_byte(vec : inout std_ulogic_vector; byteno : in natural; value : in std_ulogic_vector(7 downto 0)) is
begin
-- Support both vector directions
if vec'ascending then
vec(byteno * 8 to (byteno + 1) * 8 - 1) := value;
else
vec((byteno + 1) * 8 - 1 downto byteno * 8) := value;
end if;
end procedure;
end package body;