summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/mdio.vhd
diff options
context:
space:
mode:
authorAlexander D'hoore <dhoore.alexander@gmail.com>2017-12-15 15:37:58 +0100
committerDimitri Staessens <dimitri.staessens@ugent.be>2017-12-15 15:37:58 +0100
commitd1a1059d748955ed93a8e87c437c7eae1258293c (patch)
tree9137bc921db74bb3797b8b0f05e7a69022412522 /netfpga10g/hdl/mdio.vhd
parent8f258e469b1acea8e3ccf1485779e1db0bf5f772 (diff)
downloadraptor-d1a1059d748955ed93a8e87c437c7eae1258293c.tar.gz
raptor-d1a1059d748955ed93a8e87c437c7eae1258293c.zip
Add the linux device driver and netfpga files
This adds the device driver and netfpga files from the master thesis (in Dutch) "Implementatie van de Recursive Internet Architecture op een FPGA platform" by Alexander D'hoore.
Diffstat (limited to 'netfpga10g/hdl/mdio.vhd')
-rw-r--r--netfpga10g/hdl/mdio.vhd223
1 files changed, 223 insertions, 0 deletions
diff --git a/netfpga10g/hdl/mdio.vhd b/netfpga10g/hdl/mdio.vhd
new file mode 100644
index 0000000..1cb34fa
--- /dev/null
+++ b/netfpga10g/hdl/mdio.vhd
@@ -0,0 +1,223 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity mdio is port (
+ clk125 : in std_logic;
+ reset125 : in std_logic;
+
+ command : in std_logic_vector(0 to 27); -- operation(2) & phyaddr(5) & devaddr(5) & data_in(16)
+ data_out : out std_logic_vector(0 to 15);
+ enable : in std_logic;
+ done : out std_logic;
+
+ mdio_in : in std_logic;
+ mdio_out : out std_logic;
+ mdio_Z : out std_logic;
+ mdc : out std_logic;
+ phy_reset_n : out std_logic;
+
+ total_count : out std_logic_vector(31 downto 0);
+ address_count : out std_logic_vector(31 downto 0);
+ write_count : out std_logic_vector(31 downto 0);
+ read_count : out std_logic_vector(31 downto 0);
+ read_incr_count : out std_logic_vector(31 downto 0)
+);
+end mdio;
+
+architecture arch of mdio is
+ type state_t is (state_idle, state_preamble, state_start, state_operation,
+ state_phyaddr, state_devaddr, state_turnaround, state_data);
+
+ signal state : state_t;
+ signal state_count : natural range 0 to 32;
+
+ signal operation : std_logic_vector(0 to 1);
+ signal phyaddr : std_logic_vector(0 to 4);
+ signal devaddr : std_logic_vector(0 to 4);
+ signal data_in : std_logic_vector(0 to 15);
+
+ signal mdc_count : natural range 0 to 25;
+ signal mdc_i : std_logic;
+
+ signal total_count_i : unsigned(31 downto 0);
+ signal address_count_i : unsigned(31 downto 0);
+ signal write_count_i : unsigned(31 downto 0);
+ signal read_count_i : unsigned(31 downto 0);
+ signal read_incr_count_i : unsigned(31 downto 0);
+
+ signal done_i : std_logic;
+begin
+ phy_reset_n <= not reset125;
+ mdc <= mdc_i;
+
+ operation <= command(0 to 1);
+ phyaddr <= command(2 to 6);
+ devaddr <= command(7 to 11);
+ data_in <= command(12 to 27);
+
+ done <= done_i;
+
+ process (clk125, reset125) begin
+ if reset125 = '1' then
+ mdc_i <= '0';
+ mdc_count <= 0;
+ done_i <= '0';
+
+ elsif rising_edge(clk125) then
+ done_i <= '0';
+
+ if mdc_count = 25 - 1 then
+ mdc_count <= 0;
+ mdc_i <= not mdc_i; -- 2.5 MHz
+
+ if mdc_i = '0' then -- rising edge
+ if state = state_data and state_count = 15 then
+ done_i <= '1';
+ end if;
+ end if;
+ else
+ mdc_count <= mdc_count + 1;
+ end if;
+ end if;
+ end process;
+
+ process (mdc_i, reset125) begin
+ if reset125 = '1' then
+ state <= state_idle;
+ state_count <= 0;
+ data_out <= (others => '0');
+
+ elsif rising_edge(mdc_i) then
+ state_count <= state_count + 1;
+
+ if state = state_preamble then
+ if state_count = 31 then
+ state <= state_start;
+ state_count <= 0;
+ end if;
+ elsif state = state_start then
+ if state_count = 1 then
+ state <= state_operation;
+ state_count <= 0;
+ end if;
+ elsif state = state_operation then
+ if state_count = 1 then
+ state <= state_phyaddr;
+ state_count <= 0;
+ end if;
+ elsif state = state_phyaddr then
+ if state_count = 4 then
+ state <= state_devaddr;
+ state_count <= 0;
+ end if;
+ elsif state = state_devaddr then
+ if state_count = 4 then
+ state <= state_turnaround;
+ state_count <= 0;
+ end if;
+ elsif state = state_turnaround then
+ if state_count = 1 then
+ state <= state_data;
+ state_count <= 0;
+ end if;
+ elsif state = state_data then
+ data_out(state_count) <= mdio_in;
+
+ if state_count = 15 then
+ state <= state_idle;
+ state_count <= 0;
+ end if;
+ else -- state = state_idle
+ if enable = '1' then
+ state <= state_preamble;
+ state_count <= 0;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process (mdc_i, reset125) begin
+ if reset125 = '1' then
+ mdio_out <= '0';
+ mdio_Z <= '1';
+
+ elsif falling_edge(mdc_i) then
+ mdio_out <= '0';
+ mdio_Z <= '1';
+
+ if state = state_preamble then
+ mdio_out <= '1';
+ mdio_Z <= '0';
+
+ elsif state = state_start then
+ mdio_out <= '0';
+ mdio_Z <= '0';
+
+ elsif state = state_operation then
+ mdio_out <= operation(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_phyaddr then
+ mdio_out <= phyaddr(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_devaddr then
+ mdio_out <= devaddr(state_count);
+ mdio_Z <= '0';
+
+ elsif state = state_turnaround then
+ if operation(0) = '0' then -- write or address
+ mdio_Z <= '0';
+
+ if state_count = 0 then
+ mdio_out <= '1';
+ else
+ mdio_out <= '0';
+ end if;
+ end if;
+
+ elsif state = state_data then
+ if operation(0) = '0' then -- write or address
+ mdio_Z <= '0';
+ mdio_out <= data_in(state_count);
+ end if;
+ end if;
+ end if;
+ end process;
+
+ total_count <= std_logic_vector(total_count_i);
+ address_count <= std_logic_vector(address_count_i);
+ write_count <= std_logic_vector(write_count_i);
+ read_count <= std_logic_vector(read_count_i);
+ read_incr_count <= std_logic_vector(read_incr_count_i);
+
+ process (clk125, reset125) begin
+ if reset125 = '1' then
+ total_count_i <= (others => '0');
+ address_count_i <= (others => '0');
+ write_count_i <= (others => '0');
+ read_count_i <= (others => '0');
+ read_incr_count_i <= (others => '0');
+
+ elsif rising_edge(clk125) then
+ if done_i = '1' then
+ total_count_i <= total_count_i + 1;
+
+ if operation = "00" then
+ address_count_i <= address_count_i + 1;
+ end if;
+ if operation = "01" then
+ write_count_i <= write_count_i + 1;
+ end if;
+ if operation = "11" then
+ read_count_i <= read_count_i + 1;
+ end if;
+ if operation = "10" then
+ read_incr_count_i <= read_incr_count_i + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+end arch;