OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 33 to Rev 34
    Reverse comparison

Rev 33 → Rev 34

/funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_de2_pll_25/vhd/ALTPLL_for_DE2_50to25.vhd
0,0 → 1,344
-- megafunction wizard: %ALTPLL%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altpll
 
-- ============================================================
-- File Name: pll.vhd
-- Megafunction Name(s):
-- altpll
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 9.1 Build 350 03/24/2010 SP 2 SJ Full Version
-- ************************************************************
 
 
--Copyright (C) 1991-2010 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
 
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.all;
 
ENTITY altera_de2_pll_25 IS
PORT
(
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC
);
END altera_de2_pll_25;
 
 
ARCHITECTURE SYN OF altera_de2_pll_25 IS
 
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC ;
SIGNAL sub_wire2 : STD_LOGIC ;
SIGNAL sub_wire3 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire4_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire4 : STD_LOGIC_VECTOR (0 DOWNTO 0);
 
 
 
COMPONENT altpll
GENERIC (
clk0_divide_by : NATURAL;
clk0_duty_cycle : NATURAL;
clk0_multiply_by : NATURAL;
clk0_phase_shift : STRING;
compensate_clock : STRING;
inclk0_input_frequency : NATURAL;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
operation_mode : STRING;
port_activeclock : STRING;
port_areset : STRING;
port_clkbad0 : STRING;
port_clkbad1 : STRING;
port_clkloss : STRING;
port_clkswitch : STRING;
port_configupdate : STRING;
port_fbin : STRING;
port_inclk0 : STRING;
port_inclk1 : STRING;
port_locked : STRING;
port_pfdena : STRING;
port_phasecounterselect : STRING;
port_phasedone : STRING;
port_phasestep : STRING;
port_phaseupdown : STRING;
port_pllena : STRING;
port_scanaclr : STRING;
port_scanclk : STRING;
port_scanclkena : STRING;
port_scandata : STRING;
port_scandataout : STRING;
port_scandone : STRING;
port_scanread : STRING;
port_scanwrite : STRING;
port_clk0 : STRING;
port_clk1 : STRING;
port_clk2 : STRING;
port_clk3 : STRING;
port_clk4 : STRING;
port_clk5 : STRING;
port_clkena0 : STRING;
port_clkena1 : STRING;
port_clkena2 : STRING;
port_clkena3 : STRING;
port_clkena4 : STRING;
port_clkena5 : STRING;
port_extclk0 : STRING;
port_extclk1 : STRING;
port_extclk2 : STRING;
port_extclk3 : STRING
);
PORT (
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
);
END COMPONENT;
 
BEGIN
sub_wire4_bv(0 DOWNTO 0) <= "0";
sub_wire4 <= To_stdlogicvector(sub_wire4_bv);
sub_wire1 <= sub_wire0(0);
c0 <= sub_wire1;
sub_wire2 <= inclk0;
sub_wire3 <= sub_wire4(0 DOWNTO 0) & sub_wire2;
 
altpll_component : altpll
GENERIC MAP (
clk0_divide_by => 2,
clk0_duty_cycle => 50,
clk0_multiply_by => 1,
clk0_phase_shift => "0",
compensate_clock => "CLK0",
inclk0_input_frequency => 20000,
intended_device_family => "Cyclone II",
lpm_hint => "CBX_MODULE_PREFIX=pll",
lpm_type => "altpll",
operation_mode => "NORMAL",
port_activeclock => "PORT_UNUSED",
port_areset => "PORT_UNUSED",
port_clkbad0 => "PORT_UNUSED",
port_clkbad1 => "PORT_UNUSED",
port_clkloss => "PORT_UNUSED",
port_clkswitch => "PORT_UNUSED",
port_configupdate => "PORT_UNUSED",
port_fbin => "PORT_UNUSED",
port_inclk0 => "PORT_USED",
port_inclk1 => "PORT_UNUSED",
port_locked => "PORT_UNUSED",
port_pfdena => "PORT_UNUSED",
port_phasecounterselect => "PORT_UNUSED",
port_phasedone => "PORT_UNUSED",
port_phasestep => "PORT_UNUSED",
port_phaseupdown => "PORT_UNUSED",
port_pllena => "PORT_UNUSED",
port_scanaclr => "PORT_UNUSED",
port_scanclk => "PORT_UNUSED",
port_scanclkena => "PORT_UNUSED",
port_scandata => "PORT_UNUSED",
port_scandataout => "PORT_UNUSED",
port_scandone => "PORT_UNUSED",
port_scanread => "PORT_UNUSED",
port_scanwrite => "PORT_UNUSED",
port_clk0 => "PORT_USED",
port_clk1 => "PORT_UNUSED",
port_clk2 => "PORT_UNUSED",
port_clk3 => "PORT_UNUSED",
port_clk4 => "PORT_UNUSED",
port_clk5 => "PORT_UNUSED",
port_clkena0 => "PORT_UNUSED",
port_clkena1 => "PORT_UNUSED",
port_clkena2 => "PORT_UNUSED",
port_clkena3 => "PORT_UNUSED",
port_clkena4 => "PORT_UNUSED",
port_clkena5 => "PORT_UNUSED",
port_extclk0 => "PORT_UNUSED",
port_extclk1 => "PORT_UNUSED",
port_extclk2 => "PORT_UNUSED",
port_extclk3 => "PORT_UNUSED"
)
PORT MAP (
inclk => sub_wire3,
clk => sub_wire0
);
 
 
 
END SYN;
 
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "6"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "2"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "25.000000"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "300.000"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "2"
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
-- Retrieval info: CBX_MODULE_PREFIX: ON
/funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_de2_pll_25/ip-xact/altera_de2_pll_25.1.0.xml
0,0 → 1,100
<?xml version="1.0" encoding="UTF-8"?>
<!--Created by Kactus 2 document generator 19:39:09 ti marras 1 2011-->
<spirit:component kts_firmtype="HW" kts_producthier="IP" kts_reuselevel="Block">
<spirit:vendor>TUT</spirit:vendor>
<spirit:library>ip.hwp.misc</spirit:library>
<spirit:name>altera_de2_pll_25</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busInterfaces>
<spirit:busInterface>
<spirit:name>clk_in</spirit:name>
<spirit:displayName>clk_in</spirit:displayName>
<spirit:description>Input clock (50 MHz, DE2 PIN_N2)</spirit:description>
<spirit:busType spirit:vendor="spiritconsortium.org" spirit:library="busdef.clock" spirit:name="clock" spirit:version="1.0"/>
<spirit:abstractionType spirit:vendor="spiritconsortium.org" spirit:library="busdef.clock" spirit:name="clock_rtl" spirit:version="1.0"/>
<spirit:slave/>
<spirit:connectionRequired>false</spirit:connectionRequired>
<spirit:portMaps>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>CLK</spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>inclk0</spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
<spirit:bitsInLau>8</spirit:bitsInLau>
<spirit:endianness>little</spirit:endianness>
</spirit:busInterface>
<spirit:busInterface>
<spirit:name>clk_out</spirit:name>
<spirit:displayName>clk_out</spirit:displayName>
<spirit:description>Output clock: input clock divided by 2.</spirit:description>
<spirit:busType spirit:vendor="spiritconsortium.org" spirit:library="busdef.clock" spirit:name="clock" spirit:version="1.0"/>
<spirit:abstractionType spirit:vendor="spiritconsortium.org" spirit:library="busdef.clock" spirit:name="clock_rtl" spirit:version="1.0"/>
<spirit:master/>
<spirit:connectionRequired>false</spirit:connectionRequired>
<spirit:portMaps>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>CLK</spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>c0</spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
<spirit:bitsInLau>8</spirit:bitsInLau>
<spirit:endianness>little</spirit:endianness>
</spirit:busInterface>
</spirit:busInterfaces>
<spirit:model>
<spirit:ports>
<spirit:port>
<spirit:name>c0</spirit:name>
<spirit:wire spirit:allLogicalDirectionsAllowed="false">
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>inclk0</spirit:name>
<spirit:wire spirit:allLogicalDirectionsAllowed="false">
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:model>
<spirit:fileSets>
<spirit:fileSet>
<spirit:name>HDLsources</spirit:name>
<spirit:displayName>HDL sources</spirit:displayName>
<spirit:description>HDL sources.</spirit:description>
<spirit:file>
<spirit:name>../vhd/ALTPLL_for_DE2_50to25.vhd</spirit:name>
<spirit:fileType>vhdlSource</spirit:fileType>
<spirit:isIncludeFile spirit:externalDeclarations="false">false</spirit:isIncludeFile>
<spirit:buildCommand>
<spirit:replaceDefaultFlags>false</spirit:replaceDefaultFlags>
</spirit:buildCommand>
</spirit:file>
</spirit:fileSet>
</spirit:fileSets>
<spirit:description>25 MHz Altera ALTPLL instantiation for Cyclone II FPGA's with input clk of 50 MHz (mul = 1, div = 2)</spirit:description>
</spirit:component>
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/simple_udp_flood_example.vhd
0,0 → 1,184
-------------------------------------------------------------------------------
-- Title : Simple UDP flood example
-- Project :
-------------------------------------------------------------------------------
-- File : simple_udp_flood_example.vhd
-- Author : <alhonena@AHVEN>
-- Company :
-- Created : 2011-09-19
-- Last update: 2011-11-08
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Connect this to UDP/IP CTRL. Floods packets with adjustable
-- size.
-------------------------------------------------------------------------------
-- Copyright (c) 2011
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-09-19 1.0 alhonena Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity simple_udp_flood_example is
generic (
data_width_g : integer := 16; -- 16 for DM9000A. 32 for LAN91C111
packet_len_g : integer := 1000; -- at least 5.
target_ip_addr_g : std_logic_vector(31 downto 0) := x"0A000004";
target_ip_port_g : integer := 5000;
source_ip_port_g : integer := 6000;
disable_arp_g : integer := 0; -- Disable Address Resolution Protocol.
-- If you disable ARP, provide also target MAC address:
target_MAC_addr_g : std_logic_vector(47 downto 0) := x"000102CEF343"
-- NOTE!!!! If ARP is enabled, you NEED RX functionality in UDP/IP/Ethernet.
-- So do not disable it from those blocks if ARP is enabled.
);
 
port (
clk : in std_logic; -- 25 MHz, synchronous with UDP/IP ctrl.
rst_n : in std_logic;
 
-- TX
new_tx_out : out std_logic;
tx_len_out : out std_logic_vector( 10 downto 0 );
target_addr_out : out std_logic_vector( 31 downto 0 );
-- Use this with target_addr_in when disable_arp_g = 1:
no_arp_target_MAC_out : out std_logic_vector( 47 downto 0 ) := (others => '0');
target_port_out : out std_logic_vector( 15 downto 0 );
source_port_out : out std_logic_vector( 15 downto 0 );
tx_data_out : out std_logic_vector( data_width_g-1 downto 0 );
tx_data_valid_out : out std_logic;
tx_re_in : in std_logic;
 
-- RX
new_rx_in : in std_logic;
rx_data_valid_in : in std_logic;
rx_data_in : in std_logic_vector( data_width_g-1 downto 0 );
rx_re_out : out std_logic;
rx_erroneous_in : in std_logic;
source_addr_in : in std_logic_vector( 31 downto 0 );
source_port_in : in std_logic_vector( 15 downto 0 );
dest_port_in : in std_logic_vector( 15 downto 0 );
rx_len_in : in std_logic_vector( 10 downto 0 );
rx_error_in : in std_logic; -- this means system error, not error
-- in data caused by network etc.
-- Status:
link_up_in : in std_logic;
fatal_error_in : in std_logic; -- Something wrong with DM9000A.
 
-- Additional user outputs:
link_up_out : out std_logic
 
);
 
end simple_udp_flood_example;
 
architecture rtl of simple_udp_flood_example is
 
type state_t is (wait_init, new_packet, fill_packet, pkt_sent);
signal state_r : state_t;
signal byte_cnt_r : integer range 0 to packet_len_g;
signal pkt_cnt_r : unsigned(31 downto 0);
begin -- rtl
 
assert data_width_g = 16 or data_width_g = 32 report "Data width 16 or 32 supported." severity failure;
assert packet_len_g > 4 report "Too short packet" severity failure;
 
link_up_out <= link_up_in;
flooder: process (clk, rst_n)
begin -- process flooder
if rst_n = '0' then -- asynchronous reset (active low)
state_r <= wait_init;
pkt_cnt_r <= (others => '0');
tx_data_valid_out <= '0';
new_tx_out <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
case state_r is
 
when wait_init =>
 
if link_up_in = '1' then
state_r <= new_packet;
end if;
when new_packet =>
-- Start a new tx. Provide addresses, ports and packet length.
new_tx_out <= '1';
target_addr_out <= target_ip_addr_g;
target_port_out <= std_logic_vector(to_unsigned(target_ip_port_g,16));
source_port_out <= std_logic_vector(to_unsigned(source_ip_port_g,16));
if disable_arp_g = 1 then
no_arp_target_MAC_out <= target_MAC_addr_g;
end if;
-- This is important. The packet payload length in BYTES. This is the amount
-- of the data YOUR application is going to write through tx_data_out. No IP,
-- no UDP, no ethernet headers included. It's all automatic.
tx_len_out <= std_logic_vector(to_unsigned(packet_len_g,11));
-- You also have to provide the first data word!
-- Ethernet controllers expect little-endianness for their data bus. We swap the byte order here
-- so that when you look the bytes in the order they arrived, it looks normal (most significant
-- byte always first).
if data_width_g = 16 then
tx_data_out <= std_logic_vector(pkt_cnt_r(23 downto 16)) & std_logic_vector(pkt_cnt_r(31 downto 24));
else
tx_data_out <= std_logic_vector(pkt_cnt_r(7 downto 0)) & std_logic_vector(pkt_cnt_r(15 downto 8)) &
std_logic_vector(pkt_cnt_r(23 downto 16)) & std_logic_vector(pkt_cnt_r(31 downto 24));
end if;
-- Remember this every time you output data:
tx_data_valid_out <= '1';
-- You can also use a FIFO so that tx_data_valid_out <= not empty.
byte_cnt_r <= packet_len_g - data_width_g/8; -- count the first word, too.
 
-- let's stay in this state until we get an acknowledgement - a read enable operation.
if tx_re_in = '1' then
state_r <= fill_packet;
tx_data_valid_out <= '0'; -- remember this, otherwise the data is read multiple times. Or, use a FIFO.
end if;
 
when fill_packet =>
if (data_width_g = 16 and (byte_cnt_r = 0 or byte_cnt_r = 1)) or
(data_width_g = 32 and (byte_cnt_r = 0 or byte_cnt_r = 1 or byte_cnt_r = 2 or byte_cnt_r = 3)) then
state_r <= pkt_sent;
else
 
if data_width_g = 16 and byte_cnt_r = packet_len_g - data_width_g/8 then
-- The rest of the packet number:
tx_data_out <= std_logic_vector(pkt_cnt_r(7 downto 0)) & std_logic_vector(pkt_cnt_r(15 downto 8));
else
tx_data_out <= (others => '0'); -- just fill the rest of the packet with zeroes.
end if;
 
tx_data_valid_out <= '1';
 
if tx_re_in = '1' then
byte_cnt_r <= byte_cnt_r - data_width_g/8; -- go to the next word.
tx_data_valid_out <= '0';
end if;
end if;
 
when pkt_sent =>
pkt_cnt_r <= pkt_cnt_r + to_unsigned(1, 32);
-- Flood more packets.
state_r <= new_packet;
when others => null;
end case;
end if;
end process flooder;
 
 
-- Always read incoming RXs in case RX is enabled. Disabling RX is recommended if it is not needed.
rx_re_out <= '1';
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp_ip.vhd
0,0 → 1,341
-------------------------------------------------------------------------------
-- Title : UDP/IP
-- Project :
-------------------------------------------------------------------------------
-- File : udp_ip.vhd
-- Author : Jussi Nieminen <niemin95@galapagosinkeiju.cs.tut.fi>
-- Last update: 2010-08-18
-------------------------------------------------------------------------------
-- Description: Receives/transmits data from/to an application, inside a UDP/IP
-- packet. Also handles ARP requests.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009/09/03 1.0 niemin95 Created
-------------------------------------------------------------------------------
 
 
library ieee;
use ieee.std_logic_1164.all;
use work.udp_ip_pkg.all;
 
entity udp_ip is
 
generic (
disable_rx_g : integer := 0;
disable_arp_g : integer := 0);
 
port (
clk : in std_logic;
rst_n : in std_logic;
-- to/from application
new_tx_in : in std_logic;
tx_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 );
target_addr_in : in std_logic_vector( ip_addr_w_c-1 downto 0 );
target_port_in : in std_logic_vector( port_w_c-1 downto 0 );
source_port_in : in std_logic_vector( port_w_c-1 downto 0 );
tx_data_in : in std_logic_vector( udp_data_width_c-1 downto 0 );
tx_data_valid_in : in std_logic;
tx_re_out : out std_logic;
new_rx_out : out std_logic;
rx_data_valid_out : out std_logic;
rx_data_out : out std_logic_vector( udp_data_width_c-1 downto 0 );
rx_re_in : in std_logic;
rx_erroneous_out : out std_logic;
source_addr_out : out std_logic_vector( ip_addr_w_c-1 downto 0 );
source_port_out : out std_logic_vector( port_w_c-1 downto 0 );
dest_port_out : out std_logic_vector( port_w_c-1 downto 0 );
rx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 );
 
-- Use this when disable_arp_g = 1
no_arp_target_MAC_in : in std_logic_vector( MAC_addr_w_c-1 downto 0 ) := (others => '0');
-- to/from ethernet controller
tx_data_out : out std_logic_vector( udp_data_width_c-1 downto 0 );
tx_data_valid_out : out std_logic;
tx_re_in : in std_logic;
target_MAC_out : out std_logic_vector( MAC_addr_w_c-1 downto 0 );
new_tx_out : out std_logic;
tx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 );
tx_frame_type_out : out std_logic_vector( frame_type_w_c-1 downto 0 );
rx_data_in : in std_logic_vector( udp_data_width_c-1 downto 0 );
rx_data_valid_in : in std_logic;
rx_re_out : out std_logic;
new_rx_in : in std_logic;
rx_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 );
rx_frame_type_in : in std_logic_vector( frame_type_w_c-1 downto 0 );
rx_erroneous_in : in std_logic;
rx_error_out : out std_logic -- this means system error, not error
-- in data caused by network etc.
);
 
end udp_ip;
 
 
architecture rtl of udp_ip is
 
signal gen_ARP_rep : std_logic;
signal gen_ARP_IP : std_logic_vector( ip_addr_w_c-1 downto 0 );
signal IP_arpsnd_arp : std_logic_vector( ip_addr_w_c-1 downto 0 );
signal MAC_arp_arpsnd : std_logic_vector( MAC_addr_w_c-1 downto 0 );
signal ARP_entry_valid : std_logic;
signal MAC_request_UDP_arpsnd : std_logic;
signal MAC_arpsnd_UDP : std_logic_vector( MAC_addr_w_c-1 downto 0 );
signal MAC_valid_arpsnd_UDP : std_logic;
signal IP_UDP_arpsnd : std_logic_vector( ip_addr_w_c-1 downto 0 );
signal sending_reply_arpsnd_arp : std_logic;
signal rx_arp_done : std_logic;
signal arpsnd_tx_ready : std_logic;
 
-- to and from arpsnd
signal tx_data_from_arp : std_logic_vector( udp_data_width_c-1 downto 0 );
signal tx_data_valid_from_arp : std_logic;
signal tx_re_to_arp : std_logic;
signal tx_target_MAC_from_arp : std_logic_vector( MAC_addr_w_c-1 downto 0 );
signal tx_len_from_arp : std_logic_vector( tx_len_w_c-1 downto 0 );
signal tx_frame_type_from_arp : std_logic_vector( frame_type_w_c-1 downto 0 );
signal new_tx_from_arp : std_logic;
signal rx_data_to_arp : std_logic_vector( udp_data_width_c-1 downto 0 );
signal rx_data_valid_to_arp : std_logic;
signal new_rx_to_arp : std_logic;
signal rx_re_from_arp : std_logic;
 
-- to and from udp block
signal tx_data_from_udp : std_logic_vector( udp_data_width_c-1 downto 0 );
signal tx_data_valid_from_udp : std_logic;
signal tx_re_to_udp : std_logic;
signal tx_target_MAC_from_udp : std_logic_vector( MAC_addr_w_c-1 downto 0 );
signal tx_len_from_udp : std_logic_vector( tx_len_w_c-1 downto 0 );
signal tx_frame_type_from_udp : std_logic_vector( frame_type_w_c-1 downto 0 );
signal new_tx_from_udp : std_logic;
signal rx_data_to_udp : std_logic_vector( udp_data_width_c-1 downto 0 );
signal rx_data_valid_to_udp : std_logic;
signal new_rx_to_udp : std_logic;
signal rx_re_from_udp : std_logic;
 
-- mux select signals
signal input_select : std_logic_vector( 1 downto 0 );
signal output_select : std_logic_vector( 1 downto 0 );
 
-- mux signals
signal tx_datas : std_logic_vector( 3*udp_data_width_c-1 downto 0 );
signal tx_data_valids : std_logic_vector( 2 downto 0 );
signal tx_target_MACs : std_logic_vector( 2*MAC_addr_w_c-1 downto 0 );
signal tx_lens : std_logic_vector( 2*tx_len_w_c-1 downto 0 );
signal tx_frame_types : std_logic_vector( 2*frame_type_w_c-1 downto 0 );
signal new_txs : std_logic_vector( 1 downto 0 );
signal tx_res : std_logic_vector( 2 downto 0 );
signal rx_res : std_logic_vector( 2 downto 0 );
signal rx_datas : std_logic_vector( 3*udp_data_width_c-1 downto 0 );
signal rx_data_valids : std_logic_vector( 2 downto 0 );
signal new_rxs : std_logic_vector( 1 downto 0 );
 
signal frame_valid : std_logic;
 
-------------------------------------------------------------------------------
begin -- rtl
-------------------------------------------------------------------------------
 
 
-- | Eth ctrl |
-- ------------
-- ||
-- ---------------------------------------------
-- |UDP/IP || |
-- | --------------- |
-- | / MUX \___ |
-- | /_________________\ | |
-- | || || || | |
-- | ---------- || ----------- |
-- | | ARPSND |----------| UDP | |
-- | ---------- || ----------- |
-- | || || || |
-- | -------- data addresses etc. |
-- | | ARP3 | \\ // |
-- | -------- \\ // |
-- | \\ // |
-- ---------------------------------------------
-- || ||
-- ---------------
-- | application |
 
 
-----------------------------------------------------------------------------
-- *** MUX SIGNALS ***
 
-- forming the tx signals for the mux
tx_datas <= tx_data_in & tx_data_from_arp & tx_data_from_udp;
tx_data_valids <= tx_data_valid_in & tx_data_valid_from_arp & tx_data_valid_from_udp;
tx_target_MACs <= tx_target_MAC_from_arp & tx_target_MAC_from_udp;
tx_lens <= tx_len_from_arp & tx_len_from_udp;
tx_frame_types <= tx_frame_type_from_arp & tx_frame_type_from_udp;
new_txs <= new_tx_from_arp & new_tx_from_udp;
 
-- tx read enables from the mux
tx_re_to_udp <= tx_res(0);
tx_re_to_arp <= tx_res(1);
tx_re_out <= tx_res(2);
 
-- rx signals
 
rx_enabled: if disable_rx_g = 0 generate
 
rx_res <= rx_re_in & rx_re_from_arp & rx_re_from_udp;
rx_data_to_udp <= rx_datas( udp_data_width_c-1 downto 0 );
rx_data_to_arp <= rx_datas( 2*udp_data_width_c-1 downto udp_data_width_c );
rx_data_out <= rx_datas( 3*udp_data_width_c-1 downto 2*udp_data_width_c );
rx_data_valid_to_udp <= rx_data_valids(0);
rx_data_valid_to_arp <= rx_data_valids(1);
rx_data_valid_out <= rx_data_valids(2);
 
new_rx_to_udp <= new_rxs(0);
new_rx_to_arp <= new_rxs(1);
 
end generate rx_enabled;
-- *** /MUX SIGNALS ***
-----------------------------------------------------------------------------
 
-- Input/output select signals can have values from 0 to 2:
-- 0: UDP
-- 1: ARP
-- 2: application
data_mux : entity work.udp_arp_data_mux
generic map (
data_width_g => udp_data_width_c,
tx_len_w_g => tx_len_w_c
)
port map (
rx_data_valid_in => rx_data_valid_in,
new_rx_in => new_rx_in,
rx_data_in => rx_data_in,
rx_res_in => rx_res,
rx_re_out => rx_re_out,
rx_datas_out => rx_datas,
rx_data_valids_out => rx_data_valids,
new_rxs_out => new_rxs,
tx_datas_in => tx_datas,
tx_data_valids_in => tx_data_valids,
tx_target_MACs_in => tx_target_MACs,
tx_lens_in => tx_lens,
tx_frame_types_in => tx_frame_types,
new_txs_in => new_txs,
tx_re_in => tx_re_in,
tx_data_out => tx_data_out,
tx_data_valid_out => tx_data_valid_out,
tx_target_MAC_out => target_MAC_out,
tx_len_out => tx_len_out,
tx_frame_type_out => tx_frame_type_out,
new_tx_out => new_tx_out,
tx_res_out => tx_res,
input_select_in => input_select,
output_select_in => output_select
);
 
frame_valid <= not rx_erroneous_in;
 
arp_enabled: if disable_arp_g = 0 generate
arp_block : entity work.ARP
port map (
clk => clk,
rstn => rst_n,
new_frame_in => new_rx_to_arp,
new_word_valid_in => rx_data_valid_to_arp,
frame_re_out => rx_re_from_arp,
frame_data_in => rx_data_to_arp,
frame_valid_in => frame_valid,
frame_len_in => rx_len_in,
sending_reply_in => sending_reply_arpsnd_arp,
req_IP_in => IP_arpsnd_arp,
gen_ARP_rep_out => gen_ARP_rep,
gen_ARP_IP_out => gen_ARP_IP,
lookup_MAC_out => MAC_arp_arpsnd,
valid_entry_out => ARP_entry_valid,
done_out => rx_arp_done
);
arpsend : entity work.ARPSnd
port map (
clk => clk,
rstn => rst_n,
request_MAC_in => MAC_request_UDP_arpsnd,
targer_IP_in => IP_UDP_arpsnd,
ARP_entry_valid_in => ARP_entry_valid,
gen_ARP_reply_in => gen_ARP_rep,
gen_ARP_IP_in => gen_ARP_IP,
lookup_MAC_in => MAC_arp_arpsnd,
lookup_IP_out => IP_arpsnd_arp,
sending_reply_out => sending_reply_arpsnd_arp,
target_MAC_out => tx_target_MAC_from_arp,
requested_MAC_out => MAC_arpsnd_UDP,
req_MAC_valid_out => MAC_valid_arpsnd_UDP,
gen_frame_out => new_tx_from_arp,
frame_type_out => tx_frame_type_from_arp,
frame_size_out => tx_len_from_arp,
tx_ready_out => arpsnd_tx_ready,
wr_data_valid_out => tx_data_valid_from_arp,
wr_data_out => tx_data_from_arp,
wr_re_in => tx_re_to_arp
);
 
end generate arp_enabled;
 
arp_disabled: if disable_arp_g = 1 generate
MAC_arpsnd_UDP <= no_arp_target_MAC_in;
MAC_valid_arpsnd_UDP <= '1';
new_tx_from_arp <= '0';
arpsnd_tx_ready <= '1';
end generate arp_disabled;
 
udp_block: entity work.udp
generic map (
data_width_g => udp_data_width_c,
tx_len_w_g => tx_len_w_c
)
port map (
clk => clk,
rst_n => rst_n,
new_tx_in => new_tx_in,
tx_len_in => tx_len_in,
target_IP_in => target_addr_in,
target_port_in => target_port_in,
source_port_in => source_port_in,
new_tx_out => new_tx_from_udp,
tx_MAC_addr_out => tx_target_MAC_from_udp,
tx_len_out => tx_len_from_udp,
tx_frame_type_out => tx_frame_type_from_udp,
header_data_out => tx_data_from_udp,
header_data_valid_out => tx_data_valid_from_udp,
ethernet_re_in => tx_re_in,
new_rx_in => new_rx_to_udp,
rx_data_in => rx_data_to_udp,
rx_data_valid_in => rx_data_valid_to_udp,
rx_len_in => rx_len_in,
rx_frame_type_in => rx_frame_type_in,
rx_re_out => rx_re_from_udp,
rx_erroneous_in => rx_erroneous_in,
rx_erroneous_out => rx_erroneous_out,
new_rx_out => new_rx_out,
rx_len_out => rx_len_out,
source_IP_out => source_addr_out,
source_port_out => source_port_out,
dest_port_out => dest_port_out,
application_re_in => rx_re_in,
request_MAC_out => MAC_request_UDP_arpsnd,
IP_to_arp_out => IP_UDP_arpsnd,
requested_MAC_in => MAC_arpsnd_UDP,
req_MAC_valid_in => MAC_valid_arpsnd_UDP,
rx_arp_ready_in => rx_arp_done,
snd_req_from_arp_in => new_tx_from_arp,
tx_arp_ready_in => arpsnd_tx_ready,
rx_error_out => rx_error_out,
input_select_out => input_select,
output_select_out => output_select
);
 
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/simple_udp_receiver_example.vhd
0,0 → 1,164
-------------------------------------------------------------------------------
-- Title : Simple UDP receiver example
-- Project :
-------------------------------------------------------------------------------
-- File : simple_udp_receiver_example.vhd
-- Author : <alhonena@AHVEN>
-- Company :
-- Created : 2011-09-28
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Connect this to UDP/IP CTRL. Receives packets and blinks a led
-- every time a packet is received.
-------------------------------------------------------------------------------
-- Copyright (c) 2011
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-09-28 1.0 alhonena Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity simple_udp_receiver_example is
generic (
data_width_g : integer := 16 -- 16 for DM9000A. 32 for LAN91C111
);
 
port (
clk : in std_logic; -- 25 MHz, synchronous with UDP/IP ctrl.
rst_n : in std_logic;
 
-- TX
new_tx_out : out std_logic;
tx_len_out : out std_logic_vector( 10 downto 0 );
target_addr_out : out std_logic_vector( 31 downto 0 );
-- Use this with target_addr_in when disable_arp_g = 1:
no_arp_target_MAC_out : out std_logic_vector( 47 downto 0 ) := (others => '0');
target_port_out : out std_logic_vector( 15 downto 0 );
source_port_out : out std_logic_vector( 15 downto 0 );
tx_data_out : out std_logic_vector( data_width_g-1 downto 0 );
tx_data_valid_out : out std_logic;
tx_re_in : in std_logic;
 
-- RX
new_rx_in : in std_logic;
rx_data_valid_in : in std_logic;
rx_data_in : in std_logic_vector( data_width_g-1 downto 0 );
rx_re_out : out std_logic;
rx_erroneous_in : in std_logic;
source_addr_in : in std_logic_vector( 31 downto 0 );
source_port_in : in std_logic_vector( 15 downto 0 );
dest_port_in : in std_logic_vector( 15 downto 0 );
rx_len_in : in std_logic_vector( 10 downto 0 );
rx_error_in : in std_logic; -- this means system error, not error
-- in data caused by network etc.
-- Status:
link_up_in : in std_logic;
fatal_error_in : in std_logic; -- Something wrong with DM9000A.
 
-- Example application outputs:
link_up_out : out std_logic;
led_out : out std_logic
 
);
 
end simple_udp_receiver_example;
 
architecture rtl of simple_udp_receiver_example is
 
type state_t is (wait_init, wait_new_rx, read_packet, pkt_read);
signal state_r : state_t;
signal byte_cnt_r : integer range 0 to 1600;
signal pkt_cnt_r : unsigned(31 downto 0);
signal led_r : std_logic;
signal rx_re_r : std_logic;
begin -- rtl
 
assert data_width_g = 16 or data_width_g = 32 report "Data width 16 or 32 supported." severity failure;
 
led_out <= led_r;
link_up_out <= link_up_in;
 
rx_re_out <= rx_re_r;
flooder: process (clk, rst_n)
begin -- process flooder
if rst_n = '0' then -- asynchronous reset (active low)
state_r <= wait_init;
pkt_cnt_r <= (others => '0');
rx_re_r <= '0';
led_r <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
 
-- DEFAULT:
rx_re_r <= '0';
 
case state_r is
 
when wait_init =>
 
if link_up_in = '1' then
state_r <= wait_new_rx;
end if;
 
when wait_new_rx =>
if new_rx_in = '1' then
-- You can read source_addr_in, source_port_in, dest_port_in here if you need them.
-- E.g., if you want to receive from a particular PC for a custom protocol, it is
-- recommended that you ignore unwanted packets (coming from a wrong address or with
-- a wrong port) by reading all bytes (as shown here).
 
-- You need to take care that you read all bytes, hence the counter.
byte_cnt_r <= to_integer(unsigned(rx_len_in));
 
-- You could read the first word already here but we are not in a hurry so we
-- use just one state to read every word.
 
state_r <= read_packet;
 
-- Change the LED status:
led_r <= not led_r;
 
-- Count the packets just for fun:
pkt_cnt_r <= pkt_cnt_r + to_unsigned(1, 32);
end if;
 
when read_packet =>
if rx_data_valid_in = '1' and rx_re_r = '0' then -- note the condition, otherwise the data is read twice.
rx_re_r <= '1'; -- acknowledge the read.
-- read the data here from rx_data_in if needed.
-- Note that the endianness is "swapped", the first byte on the wire is
-- in rx_data_in(7 downto 0).
 
-- Note that byte_cnt_r here shows how many bytes we had left
-- before this read operation. Stop reading if this is the last operation.
if data_width_g = 16 then
if byte_cnt_r = 1 or byte_cnt_r = 2 then
state_r <= wait_new_rx;
else
byte_cnt_r <= byte_cnt_r - 2;
end if;
else -- data_width_g = 32
if byte_cnt_r = 1 or byte_cnt_r = 2 or byte_cnt_r = 3 or byte_cnt_r = 4 then
state_r <= wait_new_rx;
else
byte_cnt_r <= byte_cnt_r - 4;
end if;
end if;
 
end if;
when others => null;
end case;
end if;
end process flooder;
 
 
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp_ip_pkg.vhd
0,0 → 1,23
-- constants and stuff
 
library ieee;
use ieee.std_logic_1164.all;
 
package udp_ip_pkg is
 
constant udp_data_width_c : integer := 16;
constant tx_len_w_c : integer := 11;
constant ip_addr_w_c : integer := 32;
constant MAC_addr_w_c : integer := 48;
constant port_w_c : integer := 16;
constant frame_type_w_c : integer := 16;
constant ip_checksum_w_c : integer := 16;
 
constant ARP_frame_type_c : std_logic_vector( frame_type_w_c-1 downto 0 ) := x"0806";
constant IP_frame_type_c : std_logic_vector( frame_type_w_c-1 downto 0 ) := x"0800";
constant UDP_protocol_c : std_logic_vector( 7 downto 0 ) := x"11";
constant own_ip_c : std_logic_vector( ip_addr_w_c-1 downto 0 ) := x"0A00000A";
constant MAC_addr_c : std_logic_vector( MAC_addr_w_c-1 downto 0 ) := x"ACDCABBACD00";
 
end udp_ip_pkg;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/arp3.vhd
0,0 → 1,288
-------------------------------------------------------------------------------
-- arp3.vhd
--
-- Author(s): Jussi Nieminen after Ashley Partis and Jorgen Peddersen
-- Created: Feb 2001
-- Last Modified: 2009-09-03
--
-- Manages an ARP table for the network stack project. This protocol listens
-- to incoming data and when an ARP request or reply arrives, the data of the
-- source is added to the ARP table. The ARP table contains two entries.
-- When a request arrives a signal is also asserted telling the arp sender to
-- send an ARP reply when possible. The incoming data from the ethernet layer
-- is a byte stream.
-- Licenced under LGPL.
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.udp_ip_pkg.all;
 
entity ARP is
port (
clk : in std_logic; -- clock signal
rstn : in std_logic; -- asynchronous active low reset
new_frame_in : in std_logic; -- from ethernet layer indicates data arrival
new_word_valid_in : in std_logic; -- indicates a new word in the stream
frame_re_out : out std_logic;
frame_data_in : in std_logic_vector (15 downto 0); -- the stream data
frame_valid_in : in std_logic; -- indicates validity
frame_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 );
sending_reply_in : in std_logic; -- ARP sender asserts this when the reply is been transmitted
req_IP_in : in std_logic_vector (31 downto 0); -- ARP sender can request MACs for this address
gen_ARP_rep_out : out std_logic; -- tell ARP sender to generate a reply
gen_ARP_IP_out : out std_logic_vector (31 downto 0); -- destination IP for generated reply
lookup_MAC_out : out std_logic_vector (47 downto 0); -- if valid, MAC for requested IP
valid_entry_out : out std_logic; -- indicates if req_IP_in is in table
done_out : out std_logic
);
end ARP;
 
architecture ARP_arch of ARP is
 
-- State signals and types
type STATETYPE is (stIdle, stHandleARP, stOperate, stCheckValid);
signal presState : STATETYPE;
signal nextState : STATETYPE;
 
-- range of 0 to 25 should be enough, but just to be sure..
signal cnt : integer range 0 to 2**tx_len_w_c-1;
signal incCnt : std_logic; -- signal to increment cnt
signal rstCnt : std_logic; -- signal to clear cnt
 
signal latchFrameData : std_logic; -- signal to latch stream data
signal frameData_r : std_logic_vector (15 downto 0); -- register for latched data
signal shiftSourceIPIn : std_logic; -- signal to shift in source IP
signal source_IP_r : std_logic_vector (31 downto 0); -- stores source IP
signal shiftSourceMACIn : std_logic; -- signal to shift in source MAC
signal source_MAC_r : std_logic_vector (47 downto 0); -- stores source MAC
 
signal ARP_operation_r : std_logic; -- '0' for reply, '1' for request
signal determineOperation : std_logic; -- signal to latch ARP_operation_r from stream
 
signal updateARPTable : std_logic; -- this signal updates the ARP table
signal ARP_entry_IP_r : std_logic_vector (31 downto 0); -- most recent ARP entry IP
signal ARP_entry_MAC_r : std_logic_vector (47 downto 0); -- most recent ARP entry MAC
signal ARP_entry_IP_old_r : std_logic_vector (31 downto 0); -- 2nd ARP entry IP
signal ARP_entry_MAC_old_r : std_logic_vector (47 downto 0); -- 2nd ARP entry MAC
 
signal doGenARPRep : std_logic; -- asserted when an ARP reply must be generated
 
signal frame_len_r : integer range 0 to 2**tx_len_w_c-1;
signal frame_invalid_r : std_logic;
signal frame_invalid : std_logic;
signal clear_invalid : std_logic;
 
-------------------------------------------------------------------------------
begin
-------------------------------------------------------------------------------
process (clk, rstn)
begin
if rstn = '0' then -- reset state and ARP entries
 
presState <= stIdle;
ARP_entry_IP_r <= (others => '0');
ARP_entry_MAC_r <= (others => '0');
ARP_entry_IP_old_r <= (others => '0');
ARP_entry_MAC_old_r <= (others => '0');
frame_re_out <= '0';
cnt <= 0;
ARP_operation_r <= '0';
frameData_r <= (others => '0');
source_IP_r <= (others => '0');
source_MAC_r <= (others => '0');
frame_invalid_r <= '0';
gen_ARP_rep_out <= '0';
gen_ARP_IP_out <= (others => '0');
 
elsif clk'event and clk = '1' then
presState <= nextState; -- go to next state
frame_re_out <= '0';
 
if incCnt = '1' then -- handle counter
cnt <= cnt + 1;
elsif rstCnt = '1' then
cnt <= 0;
end if;
 
if latchFrameData = '1' then -- latch stream data
frameData_r <= frame_data_in;
frame_re_out <= '1';
end if;
 
if determineOperation = '1' then -- determine ARP Operation value
ARP_operation_r <= frameData_r(8);
end if;
 
if shiftSourceIPIn = '1' then -- shift in IP
source_IP_r <= source_IP_r (15 downto 0) &
frameData_r( 7 downto 0 ) & frameData_r( 15 downto 8 );
end if;
 
if shiftSourceMACIn = '1' then -- shift in MAC
source_MAC_r <= source_MAC_r (31 downto 0) &
frameData_r( 7 downto 0 ) & frameData_r( 15 downto 8 );
end if;
 
if updateARPTable = '1' then -- update ARP table
if ARP_entry_IP_r = source_IP_r then -- We already have this ARP, so update
ARP_entry_MAC_r <= source_MAC_r;
else -- Lose one old ARP entry and add new one.
ARP_entry_IP_old_r <= ARP_entry_IP_r;
ARP_entry_MAC_old_r <= ARP_entry_MAC_r;
ARP_entry_IP_r <= source_IP_r;
ARP_entry_MAC_r <= source_MAC_r;
end if;
end if;
 
if frame_invalid = '1' then
frame_invalid_r <= '1';
elsif clear_invalid = '1' then
frame_invalid_r <= '0';
end if;
 
if new_frame_in = '1' then
frame_len_r <= to_integer( unsigned( frame_len_in ));
end if;
 
-- gen_ARP_rep_out is asserted by doGenARPRep and will stay high until cleared
-- by sending_reply_in
if doGenARPRep = '1' then
gen_ARP_rep_out <= '1'; -- when a request is needed assert gen_ARP_rep_out
gen_ARP_IP_out <= source_IP_r; -- and latch the outgoing address
elsif sending_reply_in = '1' then
gen_ARP_rep_out <= '0'; -- when the request is been generated, stop requesting
end if;
end if;
end process;
 
process (presState, ARP_operation_r, cnt, new_frame_in, frame_invalid_r,
new_word_valid_in, frameData_r, frame_valid_in, frame_len_r)
begin
-- defaulting of signals
rstCnt <= '0';
incCnt <= '0';
shiftSourceIPIn <= '0';
determineOperation <= '0';
updateARPTable <= '0';
shiftSourceIPIn <= '0';
shiftSourceMACIn <= '0';
latchFrameData <= '0';
doGenARPRep <= '0';
frame_invalid <= '0';
clear_invalid <= '0';
done_out <= '0';
 
case presState is
when stIdle =>
-- wait for an ARP frame to arrive (udp_ip makes sure that it really is
-- an ARP frame)
if new_frame_in = '1' then
nextState <= stHandleARP;
rstCnt <= '1';
else
-- if there is data still coming to ARP, just pretend to be reading it
if new_word_valid_in = '1' then
latchFrameData <= '1';
end if;
nextState <= stIdle;
end if;
 
when stHandleARP =>
-- receive a byte from the stream
if new_word_valid_in = '0' then
nextState <= stHandleARP;
else
nextState <= stOperate;
latchFrameData <= '1';
end if;
 
when stOperate =>
-- increment counter
incCnt <= '1';
-- choose state based on values in the header
-- The following will make us ignore the frame (all values hexadecimal):
-- Hardware Type /= 1
-- Protocol Type /= 800
-- Hardware Length /= 6
-- Protocol Length /= 4
-- Operation /= 1 or 2
-- Target IP /= our IP (i.e. message is not meant for us)
if (cnt = 0 and frameData_r /= x"0100") or
(cnt = 1 and frameData_r /= x"0008") or -- MSByte = 0 to 7, LSByte = 8 to 15
(cnt = 2 and frameData_r /= x"0406") or
(cnt = 3 and frameData_r /= x"0100" and frameData_r /= x"0200") or
(cnt = 12 and frameData_r /= own_ip_c( 23 downto 16 ) & own_ip_c( 31 downto 24 )) or
(cnt = 13 and frameData_r /= own_ip_c( 7 downto 0 ) & own_ip_c( 15 downto 8 )) then
 
--if ((cnt = "00000" or cnt = "00011" or cnt = "00110") and frameData_r /= 0 )or
-- (cnt = "00001" and frameData_r /= 1) or
-- (cnt = "00010" and frameData_r /= 8) or
-- (cnt = "00100" and frameData_r /= 6) or
-- (cnt = "00101" and frameData_r /= 4) or
-- (cnt = "00111" and frameData_r /= 1 and frameData_r /= 2 )or
-- (cnt = "11000" and frameData_r /= DEVICE_IP (31 downto 24)) or
-- (cnt = "11001" and frameData_r /= DEVICE_IP (23 downto 16)) or
-- (cnt = "11010" and frameData_r /= DEVICE_IP (15 downto 8)) or
-- (cnt = "11011" and frameData_r /= DEVICE_IP (7 downto 0)) then
 
frame_invalid <= '1';
end if;
 
-- frame len is in bytes, so divide by two
if cnt = frame_len_r/2-1 then
nextState <= stCheckValid; -- exit when data is totally received
else
nextState <= stHandleARP; -- otherwise loop until complete
end if;
 
-- latch and shift in signals from stream when needed
if cnt = 3 then
determineOperation <= '1';
end if;
if cnt = 4 or cnt = 5 or cnt = 6 then
shiftSourceMACIn <= '1';
end if;
if cnt = 7 or cnt = 8 then
shiftSourceIPIn <= '1';
end if;
 
when stCheckValid =>
clear_invalid <= '1';
 
done_out <= '1';
nextState <= stIdle;
if frame_valid_in = '1' and frame_invalid_r = '0' then
-- frame didn't fail CRC and it's not invalid in any other way either
-- generate a reply if required and wait for more messages
if ARP_operation_r = '1' then
doGenARPRep <= '1';
end if;
updateARPTable <= '1'; -- update the ARP table with the new data
end if;
 
when others => null;
 
end case;
end process;
 
-- handle requests for entries in the ARP table.
process (req_IP_in, ARP_entry_IP_r, ARP_entry_MAC_r, ARP_entry_IP_old_r, ARP_entry_MAC_old_r)
begin
if req_IP_in = ARP_entry_IP_r then -- check most recent entry
valid_entry_out <= '1';
lookup_MAC_out <= ARP_entry_MAC_r;
elsif req_IP_in = ARP_entry_IP_old_r then -- check 2nd entry
valid_entry_out <= '1';
lookup_MAC_out <= ARP_entry_MAC_old_r;
else -- if neither entry matches, valid = 0
valid_entry_out <= '0';
lookup_MAC_out <= (others => '1');
end if;
end process;
end ARP_arch;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/arpsnd.vhd
0,0 → 1,497
-------------------------------------------------------------------------------
-- arpsnd.vhd
--
-- Author(s): Jussi Nieminen after Ashley Partis and Jorgen Peddersen
-- Created: Feb 2001
-- Last Modified: Feb 2001
--
-- Sits transparently between the internet send and ethernet send layers.
-- All frame send requests from the internet layer are passed through after
-- the destination MAC is either looked up from the ARP table, or an ARP
-- request is sent out and an ARP reply is receiver. ARP replies are created
-- and then sent to the ethernet later after being requested by the ARP layer.
-- After each frame is passed on to the ethernet layer and then sent, it informs
-- the layer above that the frame has been sent.
--
-- Licenced under LGPL.
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.udp_ip_pkg.all;
 
entity ARPSnd is
port (
clk : in std_logic; -- clock
rstn : in std_logic; -- aysnchronous active low reset
request_MAC_in : in std_logic; -- IP layer want's to know a MAC addr
targer_IP_in : in std_logic_vector (31 downto 0); -- destination IP from the internet layer
ARP_entry_valid_in : in std_logic; -- input from ARP indicating that it contains the requested IP
gen_ARP_reply_in : in std_logic; -- input from ARP requesting an ARP reply
gen_ARP_IP_in : in std_logic_vector (31 downto 0); -- input from ARP saying which IP to send a reply to
lookup_MAC_in : in std_logic_vector (47 downto 0); -- input from ARP giving a requested MAC
lookup_IP_out : out std_logic_vector (31 downto 0); -- output to ARP requesting an IP to be looked up in the table
sending_reply_out : out std_logic; -- output to ARP to tell it's sending the ARP reply
target_MAC_out : out std_logic_vector (47 downto 0); -- destination MAC for the physical layer
requested_MAC_out : out std_logic_vector( 47 downto 0 ); -- requested MAC to UDP/IP
req_MAC_valid_out : out std_logic;
gen_frame_out : out std_logic; -- tell the ethernet layer (PHY) to send a frame
frame_type_out : out std_logic_vector( frame_type_w_c-1 downto 0 );
frame_size_out : out std_logic_vector (10 downto 0); -- tell the PHY what size the frame size is
tx_ready_out : out std_logic; -- idle signal
wr_data_valid_out : out std_logic;
wr_data_out : out std_logic_vector (15 downto 0);
wr_re_in : in std_logic
);
end ARPSnd;
 
architecture ARPSnd_arch of ARPSnd is
 
-- FSM state definitions
type STATETYPE is (stIdle, stGenARPReply, stGetReplyMAC, stStoreARPReply, stCheckARPEntry, stCheckARPEntry2,
stGenARPRequest, stStoreARPRequest, stWaitForValidEntry, stGiveMAC);
signal presState : STATETYPE;
signal nextState : STATETYPE;
 
-- signals to synchronously increment and reset the counter
signal cnt : std_logic_vector (4 downto 0);
signal incCnt : std_logic;
signal rstCnt : std_logic;
 
-- next write data value
signal nextWrData : std_logic_vector (15 downto 0);
 
-- signals and buffers to latch input data
signal latchTargetIP : std_logic;
signal latchInternetIP : std_logic;
signal IP_r : std_logic_vector (31 downto 0);
signal latchTargetMAC : std_logic;
signal MAC_r : std_logic_vector (47 downto 0);
 
-- 20 second ARP reply timeout counter at 50MHz
signal ARP_timeout_cnt_r : std_logic_vector (29 downto 0);
signal rstARPCnt : std_logic;
signal ARP_cnt_overflow_r : std_logic;
 
signal wr_data_r : std_logic_vector( 15 downto 0 );
signal wr_data_valid : std_logic;
signal start_tx : std_logic;
signal MAC_to_output : std_logic;
signal req_MAC_valid_r : std_logic;
 
constant ARP_frame_size_c : std_logic_vector( 10 downto 0 ) := "00000011100";
 
-------------------------------------------------------------------------------
begin
-------------------------------------------------------------------------------
 
-- connect output to register
wr_data_out <= wr_data_r;
req_MAC_valid_out <= req_MAC_valid_r;
 
process (rstn, clk)
begin
-- set up the asynchronous active low reset
if rstn = '0' then
presState <= stIdle;
cnt <= (others => '0');
wr_data_valid_out <= '0';
wr_data_r <= (others => '0');
ARP_timeout_cnt_r <= (others => '0');
ARP_cnt_overflow_r <= '0';
IP_r <= (others => '0');
MAC_r <= (others => '0');
gen_frame_out <= '0';
target_MAC_out <= (others => '0');
frame_size_out <= (others => '0');
frame_type_out <= (others => '0');
req_MAC_valid_r <= '0';
requested_MAC_out <= (others => '0');
 
elsif clk'event and clk = '1' then
 
presState <= nextState;
-- set the write data bus to it's next value
wr_data_r <= nextWrData;
 
-- register valid signal
if wr_data_valid = '1' then
wr_data_valid_out <= '1';
end if;
 
-- start a tx
if start_tx = '1' then
if latchTargetMAC = '1' then
target_MAC_out <= lookup_MAC_in;
else
target_MAC_out <= x"FFFFFFFFFFFF";
end if;
gen_frame_out <= '1'; -- goes to 'new tx' and 'snd_req' (udp)
frame_size_out <= ARP_frame_size_c;
frame_type_out <= ARP_frame_type_c;
end if;
 
if wr_re_in = '1' then
-- clear gen_frame_out when eth cntrl starts to read
gen_frame_out <= '0';
-- also clear the valid signal
wr_data_valid_out <= '0';
end if;
 
 
-- increment and reset the counter synchronously to avoid race conditions
if incCnt = '1' then
cnt <= cnt + 1;
elsif rstCnt = '1' then
cnt <= (others => '0');
end if;
 
-- set the ARP counter to 1
if rstARPCnt = '1' then
ARP_timeout_cnt_r <= "00" & x"0000001";
ARP_cnt_overflow_r <= '0';
-- if the ARP counter isn't 0, keep incrementing it
elsif ARP_timeout_cnt_r /= "00" & x"0000000" then
ARP_timeout_cnt_r <= ARP_timeout_cnt_r + 1;
ARP_cnt_overflow_r <= '0';
-- if the counter is 0, set the overflow signal
else
ARP_cnt_overflow_r <= '1';
end if;
 
-- latch the IP to send the ARP request to, send the ARP reply to or to lookup
-- from either the ARP layer or internet send layer
if latchTargetIP = '1' then
IP_r <= gen_ARP_IP_in;
elsif latchInternetIP = '1' then
IP_r <= targer_IP_in;
end if;
 
-- latch the MAC from the ARP table that has been looked up
if latchTargetMAC = '1' then
MAC_r <= lookup_MAC_in;
end if;
 
if MAC_to_output = '1' then
-- put out the MAC when we have it
requested_MAC_out <= MAC_r;
req_MAC_valid_r <= '1';
elsif request_MAC_in = '0' then
-- clear the valid signal when IP layer stops requesting
req_MAC_valid_r <= '0';
end if;
 
end if;
end process;
 
 
 
-- ARP header format
--
-- 0 8 16 31
-- --------------------------------------------------------------------------------------------
-- | Hardware Type | Protocol Type |
-- | | |
-- --------------------------------------------------------------------------------------------
-- | Hardware Address | Protocol Address | Operation |
-- | Length | Length | |
-- --------------------------------------------------------------------------------------------
-- | Sender Hardware Address (MAC) (bytes 0 - 3) |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Sender MAC (bytes 4 - 5) | Sender IP Address (bytes 0 - 1) |
-- | | |
-- --------------------------------------------------------------------------------------------
-- | Sender IP (bytes 2 - 3) | Target Hardware Address (bytes 0 - 1) |
-- | | |
-- --------------------------------------------------------------------------------------------
-- | Target MAC (bytes 2 - 5) |
-- | |
-- --------------------------------------------------------------------------------------------
-- | Target IP Address (bytes 0 - 3) |
-- | |
-- --------------------------------------------------------------------------------------------
--
 
-- main FSM process
process (presState, gen_ARP_reply_in, cnt, IP_r, MAC_r, wr_data_r, req_MAC_valid_r,
ARP_entry_valid_in, ARP_cnt_overflow_r, request_MAC_in, wr_re_in)
begin
-- remember the value of the RAM write data bus by default
nextWrData <= wr_data_r;
-- lookup the latched IP by default
lookup_IP_out <= IP_r;
rstCnt <= '0';
incCnt <= '0';
sending_reply_out <= '0';
tx_ready_out <= '0';
latchInternetIP <= '0';
latchTargetIP <= '0';
latchTargetMAC <= '0';
rstARPCnt <= '0';
wr_data_valid <= '0';
MAC_to_output <= '0';
 
start_tx <= '0';
 
case presState is
when stIdle =>
-- wait for a frame to arrive
-- if req_MAC_valid_r = '1', we have just arrived from state stGiveMAC
-- and we don't want to get again to stCheckARPEntry.
if (req_MAC_valid_r = '1' or request_MAC_in = '0')
and gen_ARP_reply_in = '0'
then
nextState <= stIdle;
tx_ready_out <= '1';
rstCnt <= '1';
 
-- create an ARP reply when asked, giving ARP message priority
elsif gen_ARP_reply_in = '1' then
nextState <= stGetReplyMAC;
-- latch the target IP from the ARP layer
latchTargetIP <= '1';
 
-- IP layer wants to have a MAC address
else
nextState <= stCheckARPEntry;
-- latch input from the IP layer
latchInternetIP <= '1';
end if;
 
-- create the ARP reply, getting the target MAC from the ARP table
when stGetReplyMAC =>
nextState <= stGenARPReply;
lookup_IP_out <= IP_r;
latchTargetMAC <= '1';
-- tell the ARP table that we're sending the reply
sending_reply_out <= '1';
start_tx <= '1';
 
-- generate each byte of the ARP reply according to count
when stGenARPReply =>
 
wr_data_valid <= '1';
nextState <= stStoreARPReply;
 
case cnt is
 
-- Hardware type
when "00000" =>
nextWrData <= x"0100"; -- remember, it's x"LSByte MSByte"
 
-- Protocol type
when "00001" =>
nextWrData <= x"0008";
 
-- Hardware and protocol Address lengths in bytes (x"PAL HAL")
when "00010" =>
nextWrData <= x"0406";
 
-- Operation
when "00011" =>
nextWrData <= x"0200";
 
-- Sender Hardware Address bytes 1 and 0
when "00100" =>
nextWrData <= MAC_addr_c( 39 downto 32 ) & MAC_addr_c (47 downto 40);
 
-- Sender Hardware Address bytes 3 and 2
when "00101" =>
nextWrData <= MAC_addr_c( 23 downto 16 ) & MAC_addr_c (31 downto 24);
 
-- Sender Hardware Address bytes 5 and 4
when "00110" =>
nextWrData <= MAC_addr_c( 7 downto 0 ) & MAC_addr_c (15 downto 8);
 
-- Sender IP Address bytes 1 and 0
when "00111" =>
nextWrData <= own_IP_c( 23 downto 16 ) & own_IP_c (31 downto 24);
 
-- Sender IP Address bytes 3 and 2
when "01000" =>
nextWrData <= own_IP_c( 7 downto 0 ) & own_IP_c (15 downto 8);
 
-- Target Hardware Address bytes 1 and 0
when "01001" =>
nextWrData <= MAC_r( 39 downto 32 ) & MAC_r( 47 downto 40 );
 
-- Target Hardware Address bytes 3 and 2
when "01010" =>
nextWrData <= MAC_r( 23 downto 16 ) & MAC_r( 31 downto 24 );
 
-- Target Hardware Address bytes 5 and 4
when "01011" =>
nextWrData <= MAC_r( 7 downto 0 ) & MAC_r( 15 downto 8 );
 
-- Target IP Address bytes 1 and 0
when "01100" =>
nextWrData <= IP_r( 23 downto 16 ) & IP_r (31 downto 24);
 
-- Target IP Address bytes 3 and 2
when "01101" =>
nextWrData <= IP_r( 7 downto 0 ) & IP_r (15 downto 8);
 
when others => null;
end case;
 
-- store the ARP reply for the Ethernet sender
when stStoreARPReply =>
 
if wr_re_in = '1' then
if cnt = "01101" then
nextState <= stIdle;
else
nextState <= stGenARPReply;
incCnt <= '1';
end if;
 
else
nextState <= stStoreARPReply;
end if;
 
 
-----------------------------------------------------------------------------------
-- handle frames passed on to us from the Internet layer
-- check to the see if the desired IP is in the ARP table
when stCheckARPEntry =>
nextState <= stCheckARPEntry2;
lookup_IP_out <= IP_r;
 
-- check to see if the ARP entry is valid
when stCheckARPEntry2 =>
lookup_IP_out <= IP_r;
-- if it's not a valid ARP entry, then generate an ARP request to find the
-- desired MAC address
if ARP_entry_valid_in = '0' then
nextState <= stGenArpRequest;
start_tx <= '1';
-- otherwise pass the MAC to the UDP/IP block
else
nextState <= stGiveMAC;
latchTargetMAC <= '1';
end if;
 
-- create each byte of the ARP request according to cnt
when stGenARPRequest =>
 
wr_data_valid <= '1';
nextState <= stStoreARPRequest;
case cnt is
 
 
-- Hardware type
when "00000" =>
nextWrData <= x"0100"; -- remember, it's x"LSByte MSByte"
 
-- Protocol type
when "00001" =>
nextWrData <= x"0008";
 
-- Hardware and protocol Address lengths in bytes (x"PAL HAL")
when "00010" =>
nextWrData <= x"0406";
 
-- Operation
when "00011" =>
nextWrData <= x"0100";
 
-- Sender Hardware Address bytes 1 and 0
when "00100" =>
nextWrData <= MAC_addr_c( 39 downto 32 ) & MAC_addr_c (47 downto 40);
 
-- Sender Hardware Address bytes 3 and 2
when "00101" =>
nextWrData <= MAC_addr_c( 23 downto 16 ) & MAC_addr_c (31 downto 24);
 
-- Sender Hardware Address bytes 5 and 4
when "00110" =>
nextWrData <= MAC_addr_c( 7 downto 0 ) & MAC_addr_c (15 downto 8);
 
-- Sender IP Address bytes 1 and 0
when "00111" =>
nextWrData <= own_IP_c( 23 downto 16 ) & own_IP_c (31 downto 24);
 
-- Sender IP Address bytes 3 and 2
when "01000" =>
nextWrData <= own_IP_c( 7 downto 0 ) & own_IP_c (15 downto 8);
 
-- Target Hardware Address bytes 1 and 0
when "01001" =>
nextWrData <= (others => '0');
 
-- Target Hardware Address bytes 3 and 2
when "01010" =>
nextWrData <= (others => '0');
 
-- Target Hardware Address bytes 5 and 4
when "01011" =>
nextWrData <= (others => '0');
 
-- Target IP Address bytes 1 and 0
when "01100" =>
nextWrData <= IP_r( 23 downto 16 ) & IP_r (31 downto 24);
 
-- Target IP Address bytes 3 and 2
when "01101" =>
nextWrData <= IP_r( 7 downto 0 ) & IP_r (15 downto 8);
 
when others => null;
end case;
 
-- store the ARP reply for the Ethernet sender
when stStoreARPRequest =>
 
if wr_re_in = '1' then
if cnt = "01101" then
nextState <= stWaitForValidEntry;
rstARPCnt <= '1';
else
nextState <= stGenARPRequest;
incCnt <= '1';
end if;
 
else
nextState <= stStoreARPRequest;
end if;
 
 
-- wait for the ARP entry to become valid
when stWaitForValidEntry =>
-- if the ARP entry becomes valid then we fire off the reply
if ARP_entry_valid_in = '1' then
tx_ready_out <= '1';
nextState <= stGiveMAC;
latchTargetMAC <= '1';
-- otherwise give a certain amount of time for the ARP reply to come
-- back in (21.5 secs on a 50MHz clock)
else
-- if the reply doesn't come back, then inform the above layer that the
-- frame was sent. Assume the higher level protocol can account for this
-- problem, or possibly an error signal could be created once a higher level
-- protocol has been written that can accomodate this
if ARP_cnt_overflow_r = '1' then
nextState <= stIdle;
else
nextState <= stWaitForValidEntry;
end if;
end if;
lookup_IP_out <= IP_r;
 
 
when stGiveMAC =>
 
MAC_to_output <= '1';
nextState <= stIdle;
when others => nextState <= stIdle;
end case;
end process;
 
end ARPSnd_arch;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp.vhd
0,0 → 1,704
-------------------------------------------------------------------------------
-- Title : UDP/IP header handling
-- Project :
-------------------------------------------------------------------------------
-- File : udp.vhd
-- Author : Jussi Nieminen <niemin95@galapagosinkeiju.cs.tut.fi>
-- Company :
-- Last update: 2010/01/06
-- Platform :
-------------------------------------------------------------------------------
-- Description: Adds and removes UDP and IP headers to data
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009/09/16 1.0 niemin95 Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.udp_ip_pkg.all;
 
 
entity udp is
 
generic (
data_width_g : integer := 16;
tx_len_w_g : integer := 11);
 
port (
clk : in std_logic;
rst_n : in std_logic;
-- from application to udp
new_tx_in : in std_logic;
tx_len_in : in std_logic_vector( tx_len_w_g-1 downto 0 );
target_IP_in : in std_logic_vector( ip_addr_w_c-1 downto 0 );
target_port_in : in std_logic_vector( port_w_c-1 downto 0 );
source_port_in : in std_logic_vector( port_w_c-1 downto 0 );
-- from udp to eth
new_tx_out : out std_logic;
tx_MAC_addr_out : out std_logic_vector( MAC_addr_w_c-1 downto 0 );
tx_len_out : out std_logic_vector( tx_len_w_g-1 downto 0 );
tx_frame_type_out : out std_logic_vector( frame_type_w_c-1 downto 0 );
header_data_out : out std_logic_vector( data_width_g-1 downto 0 );
header_data_valid_out : out std_logic;
ethernet_re_in : in std_logic;
new_rx_in : in std_logic;
rx_data_in : in std_logic_vector( data_width_g-1 downto 0 );
rx_data_valid_in : in std_logic;
rx_len_in : in std_logic_vector( tx_len_w_g-1 downto 0 );
rx_frame_type_in : in std_logic_vector( frame_type_w_c-1 downto 0 );
rx_re_out : out std_logic;
rx_erroneous_in : in std_logic;
-- from udp to application
rx_erroneous_out : out std_logic;
new_rx_out : out std_logic;
rx_len_out : out std_logic_vector( tx_len_w_g-1 downto 0 );
source_IP_out : out std_logic_vector( ip_addr_w_c-1 downto 0 );
source_port_out : out std_logic_vector( port_w_c-1 downto 0 );
dest_port_out : out std_logic_vector( port_w_c-1 downto 0 );
application_re_in : in std_logic;
-- from udp to arpsnd
request_MAC_out : out std_logic;
IP_to_arp_out : out std_logic_vector( ip_addr_w_c-1 downto 0 );
requested_MAC_in : in std_logic_vector( MAC_addr_w_c-1 downto 0 );
req_MAC_valid_in : in std_logic;
rx_arp_ready_in : in std_logic;
snd_req_from_arp_in : in std_logic;
tx_arp_ready_in : in std_logic;
-- other control signals
rx_error_out : out std_logic;
input_select_out : out std_logic_vector( 1 downto 0 );
output_select_out : out std_logic_vector( 1 downto 0 )
);
 
end udp;
 
 
architecture rtl of udp is
 
type tx_state_type is (tx_idle, write_IP_headers, write_UDP_headers, relay_tx_data, tx_arp);
type rx_state_type is (rx_idle, read_IP_headers, read_UDP_headers, relay_rx_data,
rx_arp, rx_discard, rx_error);
type IP_header_state_type is (version_IHL_DS, IP_length, ID, flags_offset, TTL_protocol,
header_checksum, source_addr1, source_addr2,
dest_addr1, dest_addr2, discard);
type UDP_header_state_type is (source_port, dest_port, UDP_length, UDP_checksum);
 
signal rx_state_r : rx_state_type;
signal tx_state_r : tx_state_type;
signal tx_IP_state_r : IP_header_state_type;
signal tx_UDP_state_r : UDP_header_state_type;
signal rx_IP_state_r : IP_header_state_type;
signal rx_UDP_state_r : UDP_header_state_type;
 
 
signal rx_len_r : integer range 0 to 2**tx_len_w_g-1;
signal rx_re_r : std_logic;
 
signal discard_rx_r : std_logic;
 
signal tx_len_r : integer range 0 to 2**tx_len_w_g-1;
signal target_port_r : std_logic_vector( port_w_c-1 downto 0 );
signal source_port_r : std_logic_vector( port_w_c-1 downto 0 );
signal target_addr_r : std_logic_vector( ip_addr_w_c-1 downto 0 );
 
signal ip_checksum : std_logic_vector( ip_checksum_w_c-1 downto 0 );
 
signal discard_xtra_bytes_r : std_logic;
signal num_xtra_bytes_r : integer range 0 to 63;
 
constant IP_header_words_c : integer := 5; -- 32bit words
constant UDP_header_length_c : integer := 8; -- bytes
 
-- precounted part of IP checksum, including field version_IHL_DS, ID,
-- flags_offset and TTL_protocol
constant pre_counted_part_of_checksum_c : std_logic_vector( ip_checksum_w_c-1 downto 0 )
:= "0100101000010001";
 
signal tx_len_for_checksum : std_logic_vector( 15 downto 0 );
-------------------------------------------------------------------------------
begin -- rtl
-------------------------------------------------------------------------------
 
-- *********************************************************************************
-- REMEMBER!! rx_data_in(15 downto 8) = LSByte and rx_data_in(7 downto 0) = MSByte!!
-- Same goes for the tx_data_out too!
-- *********************************************************************************
 
-------------------------------------------------------------------------------
rx_re_out <= rx_re_r;
rx_process : process (clk, rst_n)
 
variable incoming_len_v : integer range 0 to 2**tx_len_w_g-1;
begin -- process rx_process
if rst_n = '0' then -- asynchronous reset (active low)
 
rx_state_r <= rx_idle;
rx_IP_state_r <= version_IHL_DS;
rx_UDP_state_r <= source_port;
 
rx_re_r <= '0';
rx_erroneous_out <= '0';
new_rx_out <= '0';
rx_len_out <= (others => '0');
source_IP_out <= (others => '0');
source_port_out <= (others => '0');
dest_port_out <= (others => '0');
discard_rx_r <= '0';
discard_xtra_bytes_r <= '0';
num_xtra_bytes_r <= 0;
 
input_select_out <= (others => '0');
 
rx_error_out <= '0';
 
elsif clk'event and clk = '1' then -- rising clock edge
 
case rx_state_r is
when rx_idle =>
 
new_rx_out <= '0';
rx_len_out <= (others => '0');
source_IP_out <= (others => '0');
source_port_out <= (others => '0');
dest_port_out <= (others => '0');
rx_erroneous_out <= '0';
 
discard_rx_r <= '0';
discard_xtra_bytes_r <= '0';
num_xtra_bytes_r <= 0;
 
if new_rx_in = '1' then
 
if rx_frame_type_in = ARP_frame_type_c then
-- arp packet goes straight to arp
rx_state_r <= rx_arp;
elsif rx_frame_type_in = IP_frame_type_c then
-- data transfer coming, start reading the headers
rx_state_r <= read_IP_headers;
rx_IP_state_r <= version_IHL_DS;
rx_len_r <= to_integer( unsigned( rx_len_in ));
rx_erroneous_out <= rx_erroneous_in;
 
else
-- whoaa, unknown protocol, discard
rx_len_r <= to_integer( unsigned( rx_len_in ));
rx_state_r <= rx_discard;
end if;
end if;
 
when read_IP_headers =>
 
if rx_data_valid_in = '1' and rx_re_r = '0' then
rx_re_r <= '1';
end if;
if rx_data_valid_in = '1' and rx_re_r = '1' then
rx_re_r <= '0';
 
-------------------------------------------------------------------
-- sub FSM handling the different fields of tx
case rx_IP_state_r is
when version_IHL_DS =>
 
-- 0_____________4_______________8_________________________16
-- | version | header length | Differentiated Services |
 
-- only thing we are interested of is the header length
-- if there's options-fields (over 5 32bit words in the header)
-- we simply discard this transmission
if to_integer( unsigned( rx_data_in(3 downto 0) )) /= IP_header_words_c then
discard_rx_r <= '1';
end if;
rx_IP_state_r <= IP_length;
 
when IP_length =>
 
-- total length of the packet, including header and the data.
incoming_len_v := to_integer( unsigned( rx_data_in(7 downto 0 ) & rx_data_in( 15 downto 8 ) ));
 
-- +1, because when reading two bytes at a time, we don't need
-- to read any xtra if rx_len = incoming_len_v + 1
if rx_len_r > incoming_len_v + 1 then
-- amount of data is less than ethernet minimum frame size (64 bytes)
-- we have to discard the extra bytes after data has been relayed.
discard_xtra_bytes_r <= '1';
 
-- getting rid of the last bit, because with odd lengths one
-- of the xtra bytes is already read out with the last databyte
num_xtra_bytes_r <= (( rx_len_r - incoming_len_v ) / 2 ) * 2;
elsif rx_len_r /= incoming_len_v and rx_len_r /= incoming_len_v + 1 then
-- there's something wrong
rx_state_r <= rx_error;
end if;
 
rx_len_r <= incoming_len_v;
rx_IP_state_r <= ID;
 
when ID =>
-- we don't care about this field
rx_IP_state_r <= flags_offset;
when flags_offset =>
-- we don't care about the flags or the offset either
rx_IP_state_r <= TTL_protocol;
 
when TTL_protocol =>
 
-- 0______________8______________16
-- | Time To Live | Protocol |
-- check that the protocol is UDP and TTL /= 0,
-- otherwise discard this transmission
if to_integer( unsigned( rx_data_in( 7 downto 0 ) )) = 0 or
rx_data_in( 15 downto 8 ) /= UDP_protocol_c
then
discard_rx_r <= '1';
end if;
rx_IP_state_r <= header_checksum;
 
when header_checksum =>
 
-- checksum check not implemented yet, maybe some day...
rx_IP_state_r <= source_addr1;
 
when source_addr1 =>
 
source_IP_out( 31 downto 24 ) <= rx_data_in( 7 downto 0 );
source_IP_out( 23 downto 16 ) <= rx_data_in( 15 downto 8 );
rx_IP_state_r <= source_addr2;
 
when source_addr2 =>
 
source_IP_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
source_IP_out( 7 downto 0 ) <= rx_data_in( 15 downto 8 );
rx_IP_state_r <= dest_addr1;
 
when dest_addr1 =>
 
-- just check that the addr matches
if rx_data_in( 7 downto 0 ) /= own_ip_c( 31 downto 24 ) or
rx_data_in( 15 downto 8 ) /= own_ip_c( 23 downto 16 )
then
-- some multicast messages contain a certain IP, so we might
-- get packets with wrong address
discard_rx_r <= '1';
end if;
rx_IP_state_r <= dest_addr2;
 
when dest_addr2 =>
 
if (rx_data_in( 7 downto 0 ) /= own_ip_c( 15 downto 8 ) or
rx_data_in( 15 downto 8 ) /= own_ip_c( 7 downto 0 ))
or discard_rx_r = '1'
then
-- if message is to be discarded, go and discard it, otherwise
-- start reading UDP headers
rx_IP_state_r <= discard;
-- there might also be extra bytes to discard, so add them to
-- the length and remove IP header length
rx_len_r <= rx_len_r + num_xtra_bytes_r - ( IP_header_words_c*4 );
else
rx_state_r <= read_UDP_headers;
rx_UDP_state_r <= source_port;
rx_IP_state_r <= version_IHL_DS;
 
-- remove IP header length
rx_len_r <= rx_len_r - ( IP_header_words_c * 4 );
end if;
 
 
when discard =>
 
-- just pretend to be reading
if rx_len_r <= 2 then
-- all done
rx_len_r <= 0;
rx_IP_state_r <= version_IHL_DS;
rx_state_r <= rx_idle;
else
rx_len_r <= rx_len_r - 2;
end if;
when others => null;
end case;
-- /rx_IP_state_r
-------------------------------------------------------------------
end if;
 
 
when read_UDP_headers =>
 
if rx_data_valid_in = '1' and rx_re_r = '0' then
rx_re_r <= '1';
end if;
if rx_data_valid_in = '1' and rx_re_r = '1' then
rx_re_r <= '0';
 
-- FSM to read the UDP header
-------------------------------------------------------------------
case rx_UDP_state_r is
when source_port =>
 
source_port_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
source_port_out( 7 downto 0 ) <= rx_data_in( 15 downto 8 );
rx_UDP_state_r <= dest_port;
 
when dest_port =>
 
dest_port_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 );
dest_port_out( 7 downto 0 ) <= rx_data_in( 15 downto 8 );
rx_UDP_state_r <= UDP_length;
 
when UDP_length =>
 
-- check that the length field is correct
if rx_len_r /=
to_integer( unsigned( rx_data_in(7 downto 0 ) & rx_data_in( 15 downto 8 ) ))
then
rx_state_r <= rx_error;
end if;
rx_UDP_state_r <= UDP_checksum;
 
when UDP_checksum =>
 
-- umm, it's propably correct...
-- give rx_data to application
input_select_out <= "10";
rx_state_r <= relay_rx_data;
-- notify application about new tx
new_rx_out <= '1';
rx_len_out <= std_logic_vector( to_unsigned( rx_len_r -
UDP_header_length_c,
tx_len_w_g ));
rx_UDP_state_r <= source_port;
rx_len_r <= rx_len_r - UDP_header_length_c;
when others => null;
end case;
-- /rx_UDP_state_r
-------------------------------------------------------------------
end if;
 
when relay_rx_data =>
 
-- monitor application_re
if application_re_in = '1' and rx_data_valid_in = '1' then
 
new_rx_out <= '0';
if rx_len_r <= 2 then
-- all received
input_select_out <= "00";
 
-- if there is extra bytes
if discard_xtra_bytes_r = '1' then
rx_state_r <= rx_discard;
rx_len_r <= num_xtra_bytes_r;
discard_xtra_bytes_r <= '0';
num_xtra_bytes_r <= 0;
else
rx_state_r <= rx_idle;
rx_len_r <= 0;
end if;
else
rx_len_r <= rx_len_r - 2;
end if;
end if;
 
 
when rx_arp =>
 
-- give turn to arp until it says it's ready
input_select_out <= "01";
if rx_arp_ready_in = '1' then
input_select_out <= "00";
rx_state_r <= rx_idle;
end if;
 
when rx_discard =>
-- we come here, if the frame type of ethernet frame is something
-- else than ARP or IP or if there is extra bytes in the frame (less
-- data than minimum ethernet frame size)
if rx_data_valid_in = '1' and rx_re_r = '0' then
rx_re_r <= '1';
end if;
if rx_data_valid_in = '1' and rx_re_r = '1' then
rx_re_r <= '0';
 
-- just pretend to be reading
if rx_len_r <= 2 then
-- all done
rx_len_r <= 0;
rx_state_r <= rx_idle;
else
rx_len_r <= rx_len_r - 2;
end if;
end if;
when rx_error =>
 
-- shit just hit the fan
rx_error_out <= '1';
when others => null;
end case;
 
end if;
end process rx_process;
-------------------------------------------------------------------------------
 
tx_len_for_checksum <= std_logic_vector( to_unsigned( tx_len_r, 16 ));
-- IP checksum computation
checksum_adder: entity work.ip_checksum
generic map (
pre_counted_part_g => pre_counted_part_of_checksum_c
)
port map (
total_length_field_in => tx_len_for_checksum,
source_addr_field_in => own_ip_c,
dest_addr_field_in => target_addr_r,
header_checksum_out => ip_checksum
);
 
-------------------------------------------------------------------------------
 
tx_process: process (clk, rst_n)
 
variable tx_len_v : integer range 0 to 2**tx_len_w_g-1;
variable tx_len_slv_v : std_logic_vector( 15 downto 0 );
begin -- process tx_process
if rst_n = '0' then -- asynchronous reset (active low)
 
tx_state_r <= tx_idle;
tx_IP_state_r <= version_IHL_DS;
tx_UDP_state_r <= source_port;
output_select_out <= (others => '0');
tx_len_r <= 0;
target_addr_r <= (others => '0');
target_port_r <= (others => '0');
source_port_r <= (others => '0');
 
request_MAC_out <= '0';
IP_to_arp_out <= (others => '0');
new_tx_out <= '0';
tx_MAC_addr_out <= (others => '0');
tx_len_out <= (others => '0');
tx_frame_type_out <= (others => '0');
header_data_out <= (others => '0');
header_data_valid_out <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
 
case tx_state_r is
when tx_idle =>
 
-- if arp want's to send, give it the output
if snd_req_from_arp_in = '1' then
tx_state_r <= tx_arp;
 
elsif new_tx_in = '1' then
 
if req_MAC_valid_in = '1' then
-- MAC found from the ARP table, start sending
tx_state_r <= write_IP_headers;
-- write first word here already (version_IHL_DS)
-- first the version, IPv4
header_data_out( 7 downto 4 ) <= "0100";
-- then header length in words
header_data_out( 3 downto 0 ) <= std_logic_vector( to_unsigned( IP_header_words_c, 4 ));
-- then Differentiated Services (just zeros)
header_data_out( 15 downto 8 ) <= (others => '0');
header_data_valid_out <= '1';
 
tx_len_v := to_integer( unsigned( tx_len_in )) +
IP_header_words_c*4 + UDP_header_length_c;
tx_len_r <= tx_len_v;
tx_len_out <= std_logic_vector( to_unsigned( tx_len_v, tx_len_w_g ));
new_tx_out <= '1';
tx_frame_type_out <= IP_frame_type_c;
source_port_r <= source_port_in;
target_port_r <= target_port_in;
target_addr_r <= target_IP_in;
tx_MAC_addr_out <= requested_MAC_in;
 
request_MAC_out <= '0';
 
else
-- We must get the MAC address before we can start sending
request_MAC_out <= '1';
IP_to_arp_out <= target_IP_in;
end if;
end if;
 
 
when write_IP_headers =>
 
if ethernet_re_in = '1' then
-- the data of the next state is written during the previous one
case tx_IP_state_r is
when version_IHL_DS =>
new_tx_out <= '0';
tx_IP_state_r <= IP_length;
 
-- remember, data goes in as 2 bytes, not as single 16-bit word
tx_len_slv_v := std_logic_vector( to_unsigned( tx_len_r, 16 ));
header_data_out <= tx_len_slv_v( 7 downto 0 ) & tx_len_slv_v( 15 downto 8 );
 
when IP_length =>
tx_IP_state_r <= ID;
header_data_out <= (others => '0');
 
when ID =>
tx_IP_state_r <= flags_offset;
header_data_out <= (others => '0');
 
when flags_offset =>
 
tx_IP_state_r <= TTL_protocol;
-- this block is made for direct communication, not router
-- networks, so 1 to TTL field should do. Still, just in case,
-- we'll put there a 5.
header_data_out( 7 downto 0 ) <= "00000101";
-- protocol is UDP
header_data_out( 15 downto 8 ) <= UDP_protocol_c;
 
when TTL_protocol =>
tx_IP_state_r <= header_checksum;
header_data_out <= ip_checksum( 7 downto 0 ) & ip_checksum( 15 downto 8 );
 
when header_checksum =>
tx_IP_state_r <= source_addr1;
header_data_out <= own_ip_c( 23 downto 16 ) & own_ip_c( 31 downto 24 );
 
when source_addr1 =>
tx_IP_state_r <= source_addr2;
header_data_out <= own_ip_c( 7 downto 0 ) & own_ip_c( 15 downto 8 );
 
when source_addr2 =>
tx_IP_state_r <= dest_addr1;
header_data_out <= target_addr_r( 23 downto 16 ) & target_addr_r( 31 downto 24 );
 
when dest_addr1 =>
tx_IP_state_r <= dest_addr2;
header_data_out <= target_addr_r( 7 downto 0 ) & target_addr_r( 15 downto 8 );
 
when dest_addr2 =>
-- all written, move on to write the UDP addr
tx_state_r <= write_UDP_headers;
tx_IP_state_r <= version_IHL_DS;
-- first UDP data
header_data_out <= source_port_r( 7 downto 0 ) & source_port_r( 15 downto 8 );
when others => null;
end case;
end if;
 
when write_UDP_headers =>
 
if ethernet_re_in = '1' then
 
case tx_UDP_state_r is
when source_port =>
tx_UDP_state_r <= dest_port;
header_data_out <= target_port_r( 7 downto 0 ) & target_port_r( 15 downto 8 );
 
when dest_port =>
tx_UDP_state_r <= UDP_length;
tx_len_slv_v := std_logic_vector( to_unsigned( tx_len_r -
IP_header_words_c*4, 16 ));
header_data_out <= tx_len_slv_v( 7 downto 0 ) & tx_len_slv_v( 15 downto 8 );
 
when UDP_length =>
tx_UDP_state_r <= UDP_checksum;
-- not used
header_data_out <= (others => '0');
 
when UDP_checksum =>
 
-- all done, start relaying the data
header_data_valid_out <= '0';
header_data_out <= (others => '0');
tx_UDP_state_r <= source_port;
tx_state_r <= relay_tx_data;
output_select_out <= "10";
-- remove headers from length
tx_len_r <= tx_len_r - IP_header_words_c*4 - UDP_header_length_c;
when others => null;
end case;
end if;
 
 
when relay_tx_data =>
 
-- count the amount of sent data and go back to idle after all is sent
if ethernet_re_in = '1' then
 
if tx_len_r <= 2 then
-- all sent
tx_len_r <= 0;
tx_state_r <= tx_idle;
output_select_out <= "00";
 
else
tx_len_r <= tx_len_r - 2;
end if;
end if;
 
when tx_arp =>
 
-- give output to arp
output_select_out <= "01";
 
-- wait until it's idle again
if tx_arp_ready_in = '1' then
output_select_out <= "00";
tx_state_r <= tx_idle;
end if;
when others => null;
end case;
end if;
end process tx_process;
 
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp_ip_dm9000a.vhd
0,0 → 1,178
-------------------------------------------------------------------------------
-- Title : UDP/IP and DM9kA Controller
-- Project :
-------------------------------------------------------------------------------
-- File : udp_ip_and_dm9ka_ctrl.vhd
-- Author : <alhonena@AHVEN>
-- Company :
-- Created : 2011-09-19
-- Last update: 2011-11-07
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Direct interface for TX and RX operations on UDP/IP protocol
-- level with external DM9000A chip (e.g. Altera DE2).
-------------------------------------------------------------------------------
-- Copyright (c) 2011
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-09-19 1.0 alhonena Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity udp_ip_dm9000a is
 
generic (
disable_rx_g : integer := 0;
disable_arp_g : integer := 0); -- If you disable ARP, you must provide
-- target MAC address (no_arp_target_MAC_in)
-- with target IP address (target_addr_in)
 
port (
clk : in std_logic; -- 25 MHz clock. DM9000A is used synchronously with UDP/IP with this clock.
rst_n : in std_logic;
 
-- to/from application
 
-- TX
new_tx_in : in std_logic;
tx_len_in : in std_logic_vector( 10 downto 0 );
target_addr_in : in std_logic_vector( 31 downto 0 );
-- Use this with target_addr_in when disable_arp_g = 1:
no_arp_target_MAC_in : in std_logic_vector( 47 downto 0 ) := (others => '0');
target_port_in : in std_logic_vector( 15 downto 0 );
source_port_in : in std_logic_vector( 15 downto 0 );
tx_data_in : in std_logic_vector( 15 downto 0 );
tx_data_valid_in : in std_logic;
tx_re_out : out std_logic;
 
-- RX
new_rx_out : out std_logic;
rx_data_valid_out : out std_logic;
rx_data_out : out std_logic_vector( 15 downto 0 );
rx_re_in : in std_logic;
rx_erroneous_out : out std_logic;
source_addr_out : out std_logic_vector( 31 downto 0 );
source_port_out : out std_logic_vector( 15 downto 0 );
dest_port_out : out std_logic_vector( 15 downto 0 );
rx_len_out : out std_logic_vector( 10 downto 0 );
rx_error_out : out std_logic; -- this means system error, not error
-- in data caused by network etc.
-- Status:
link_up_out : out std_logic;
fatal_error_out : out std_logic; -- Something wrong with DM9000A.
 
-- To the external ethernet chip (Davicom DM9000A)
eth_clk_out : out std_logic;
eth_reset_out : out std_logic;
eth_cmd_out : out std_logic;
eth_write_out : out std_logic;
eth_read_out : out std_logic;
eth_interrupt_in : in std_logic;
eth_data_inout : inout std_logic_vector( 15 downto 0 );
eth_chip_sel_out : out std_logic
 
);
 
end udp_ip_dm9000a;
 
architecture structural of udp_ip_dm9000a is
 
signal tx_data : std_logic_vector(15 downto 0);
signal tx_data_valid : std_logic;
signal tx_re : std_logic;
signal rx_re : std_logic;
signal rx_data : std_logic_vector(15 downto 0);
signal rx_data_valid : std_logic;
signal target_MAC : std_logic_vector(47 downto 0);
signal new_tx : std_logic;
signal tx_len : std_logic_vector(10 downto 0);
signal tx_frame_type : std_logic_vector(15 downto 0);
signal new_rx : std_logic;
signal rx_len : std_logic_vector(10 downto 0);
signal rx_frame_type : std_logic_vector(15 downto 0);
signal rx_erroneous : std_logic;
begin -- structural
 
assert not (disable_rx_g = 1 and disable_arp_g = 0) report "RX must be enabled if ARP is enabled" severity failure;
assert disable_rx_g = 0 or disable_rx_g = 1 report "illegal value of disable_rx_g" severity failure;
assert disable_arp_g = 0 or disable_arp_g = 1 report "illegal value of disable_arp_g" severity failure;
 
DM9kA_controller_1: entity work.DM9kA_controller
generic map (
disable_rx_g => disable_rx_g)
port map (
clk => clk,
rst_n => rst_n,
eth_clk_out => eth_clk_out,
eth_reset_out => eth_reset_out,
eth_cmd_out => eth_cmd_out,
eth_write_out => eth_write_out,
eth_read_out => eth_read_out,
eth_interrupt_in => eth_interrupt_in,
eth_data_inout => eth_data_inout,
eth_chip_sel_out => eth_chip_sel_out,
tx_data_in => tx_data,
tx_data_valid_in => tx_data_valid,
tx_re_out => tx_re,
rx_re_in => rx_re,
rx_data_out => rx_data,
rx_data_valid_out => rx_data_valid,
target_MAC_in => target_MAC,
new_tx_in => new_tx,
tx_len_in => tx_len,
tx_frame_type_in => tx_frame_type,
new_rx_out => new_rx,
rx_len_out => rx_len,
rx_frame_type_out => rx_frame_type,
rx_erroneous_out => rx_erroneous,
ready_out => link_up_out,
fatal_error_out => fatal_error_out);
 
udp_ip_1: entity work.udp_ip
generic map (
disable_rx_g => disable_rx_g,
disable_arp_g => disable_arp_g)
port map (
clk => clk,
rst_n => rst_n,
new_tx_in => new_tx_in,
tx_len_in => tx_len_in,
target_addr_in => target_addr_in,
target_port_in => target_port_in,
source_port_in => source_port_in,
tx_data_in => tx_data_in,
tx_data_valid_in => tx_data_valid_in,
tx_re_out => tx_re_out,
new_rx_out => new_rx_out,
rx_data_valid_out => rx_data_valid_out,
rx_data_out => rx_data_out,
rx_re_in => rx_re_in,
rx_erroneous_out => rx_erroneous_out,
source_addr_out => source_addr_out,
source_port_out => source_port_out,
dest_port_out => dest_port_out,
rx_len_out => rx_len_out,
no_arp_target_MAC_in => no_arp_target_MAC_in,
tx_data_out => tx_data,
tx_data_valid_out => tx_data_valid,
tx_re_in => tx_re,
target_MAC_out => target_MAC,
new_tx_out => new_tx,
tx_len_out => tx_len,
tx_frame_type_out => tx_frame_type,
rx_data_in => rx_data,
rx_data_valid_in => rx_data_valid,
rx_re_out => rx_re,
new_rx_in => new_rx,
rx_len_in => rx_len,
rx_frame_type_in => rx_frame_type,
rx_erroneous_in => rx_erroneous,
rx_error_out => rx_error_out);
end structural;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp_ip_lan91c111.vhd
0,0 → 1,218
-------------------------------------------------------------------------------
-- Title : UDP/IP and LAN91C111 Controller
-- Project :
-------------------------------------------------------------------------------
-- File : udp_ip_lan91c111.vhd
-- Author : <alhonena@AHVEN>
-- Company :
-- Created : 2011-09-19
-- Last update: 2011-11-07
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Direct interface for TX and RX operations on UDP/IP protocol
-- level with external LAN91C111 chip (e.g. Altera Stratix II S180 dev board)
-- This toplevel uses a 16-bit mode of LAN91C111 controller!
-------------------------------------------------------------------------------
-- Copyright (c) 2011
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-09-19 1.0 alhonena Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
entity udp_ip_lan91c111 is
 
generic (
disable_rx_g : integer := 0;
disable_arp_g : integer := 0); -- If you disable ARP, you must provide
-- target MAC address (no_arp_target_MAC_in)
-- with target IP address (target_addr_in)
 
port (
clk : in std_logic; -- 25 MHz clock to ensure proper timing. LAN91C111 is used asynchronously.
rst_n : in std_logic;
 
-- to/from application
 
-- TX
new_tx_in : in std_logic;
tx_len_in : in std_logic_vector( 10 downto 0 );
target_addr_in : in std_logic_vector( 31 downto 0 );
-- Use this with target_addr_in when disable_arp_g = 1:
no_arp_target_MAC_in : in std_logic_vector( 47 downto 0 ) := (others => '0');
target_port_in : in std_logic_vector( 15 downto 0 );
source_port_in : in std_logic_vector( 15 downto 0 );
tx_data_in : in std_logic_vector( 15 downto 0 );
tx_data_valid_in : in std_logic;
tx_re_out : out std_logic;
 
-- RX
new_rx_out : out std_logic;
rx_data_valid_out : out std_logic;
rx_data_out : out std_logic_vector( 15 downto 0 );
rx_re_in : in std_logic;
rx_erroneous_out : out std_logic;
source_addr_out : out std_logic_vector( 31 downto 0 );
source_port_out : out std_logic_vector( 15 downto 0 );
dest_port_out : out std_logic_vector( 15 downto 0 );
rx_len_out : out std_logic_vector( 10 downto 0 );
rx_error_out : out std_logic; -- this means system error, not error
-- in data caused by network etc.
-- Status:
link_up_out : out std_logic;
fatal_error_out : out std_logic; -- Something wrong with LAN91C111.
 
-- To the external ethernet chip (SMSC LAN91C111)
eth_data_inout : inout std_logic_vector( 31 downto 0 );
eth_addr_out : out std_logic_vector( 14 downto 0 ); -- note that they start indexing from 1! A1 on the datasheet goes to eth_addr_out(0).
eth_interrupt_in : in std_logic;
eth_read_out : out std_logic;
eth_write_out : out std_logic;
eth_nADS_out : out std_logic;
eth_nAEN_out : out std_logic;
eth_nBE_out : out std_logic_vector(3 downto 0)
);
 
end udp_ip_lan91c111;
 
architecture structural of udp_ip_lan91c111 is
 
signal tx_data : std_logic_vector(15 downto 0);
signal tx_data_valid : std_logic;
signal tx_re : std_logic;
signal rx_re : std_logic;
signal rx_data : std_logic_vector(15 downto 0);
signal rx_data_valid : std_logic;
signal target_MAC : std_logic_vector(47 downto 0);
signal new_tx : std_logic;
signal tx_len : std_logic_vector(10 downto 0);
signal tx_frame_type : std_logic_vector(15 downto 0);
signal new_rx : std_logic;
signal rx_len : std_logic_vector(10 downto 0);
signal rx_frame_type : std_logic_vector(15 downto 0);
signal rx_erroneous : std_logic;
begin -- structural
 
assert not (disable_rx_g = 1 and disable_arp_g = 0) report "RX must be enabled if ARP is enabled" severity failure;
assert disable_rx_g = 0 or disable_rx_g = 1 report "illegal value of disable_rx_g" severity failure;
assert disable_arp_g = 0 or disable_arp_g = 1 report "illegal value of disable_arp_g" severity failure;
rx_disable: if disable_rx_g = 1 generate
lan91c111_controller_1: entity work.lan91c111_controller
generic map (
enable_rx_g => '0',
interface_width_g => 16)
port map (
clk => clk,
rst_n => rst_n,
eth_data_inout => eth_data_inout,
eth_addr_out => eth_addr_out,
eth_interrupt_in => eth_interrupt_in,
eth_read_out => eth_read_out,
eth_write_out => eth_write_out,
eth_nADS_out => eth_nADS_out,
eth_nAEN_out => eth_nAEN_out,
eth_nBE_out => eth_nBE_out,
tx_data_in => tx_data,
tx_data_valid_in => tx_data_valid,
tx_re_out => tx_re,
rx_re_in => rx_re,
rx_data_out => rx_data,
rx_data_valid_out => rx_data_valid,
target_MAC_in => target_MAC,
new_tx_in => new_tx,
tx_len_in => tx_len,
tx_frame_type_in => tx_frame_type,
new_rx_out => new_rx,
rx_len_out => rx_len,
rx_frame_type_out => rx_frame_type,
rx_erroneous_out => rx_erroneous,
ready_out => link_up_out,
fatal_error_out => fatal_error_out);
end generate rx_disable;
 
rx_enable: if disable_rx_g = 0 generate
lan91c111_controller_1: entity work.lan91c111_controller
generic map (
enable_rx_g => '1',
interface_width_g => 16)
port map (
clk => clk,
rst_n => rst_n,
eth_data_inout => eth_data_inout,
eth_addr_out => eth_addr_out,
eth_interrupt_in => eth_interrupt_in,
eth_read_out => eth_read_out,
eth_write_out => eth_write_out,
eth_nADS_out => eth_nADS_out,
eth_nAEN_out => eth_nAEN_out,
eth_nBE_out => eth_nBE_out,
tx_data_in => tx_data,
tx_data_valid_in => tx_data_valid,
tx_re_out => tx_re,
rx_re_in => rx_re,
rx_data_out => rx_data,
rx_data_valid_out => rx_data_valid,
target_MAC_in => target_MAC,
new_tx_in => new_tx,
tx_len_in => tx_len,
tx_frame_type_in => tx_frame_type,
new_rx_out => new_rx,
rx_len_out => rx_len,
rx_frame_type_out => rx_frame_type,
rx_erroneous_out => rx_erroneous,
ready_out => link_up_out,
fatal_error_out => fatal_error_out);
end generate rx_enable;
 
udp_ip_1: entity work.udp_ip
generic map (
disable_rx_g => disable_rx_g,
disable_arp_g => disable_arp_g)
port map (
clk => clk,
rst_n => rst_n,
new_tx_in => new_tx_in,
tx_len_in => tx_len_in,
target_addr_in => target_addr_in,
target_port_in => target_port_in,
source_port_in => source_port_in,
tx_data_in => tx_data_in,
tx_data_valid_in => tx_data_valid_in,
tx_re_out => tx_re_out,
new_rx_out => new_rx_out,
rx_data_valid_out => rx_data_valid_out,
rx_data_out => rx_data_out,
rx_re_in => rx_re_in,
rx_erroneous_out => rx_erroneous_out,
source_addr_out => source_addr_out,
source_port_out => source_port_out,
dest_port_out => dest_port_out,
rx_len_out => rx_len_out,
no_arp_target_MAC_in => no_arp_target_MAC_in,
tx_data_out => tx_data,
tx_data_valid_out => tx_data_valid,
tx_re_in => tx_re,
target_MAC_out => target_MAC,
new_tx_out => new_tx,
tx_len_out => tx_len,
tx_frame_type_out => tx_frame_type,
rx_data_in => rx_data,
rx_data_valid_in => rx_data_valid,
rx_re_out => rx_re,
new_rx_in => new_rx,
rx_len_in => rx_len,
rx_frame_type_in => rx_frame_type,
rx_erroneous_in => rx_erroneous,
rx_error_out => rx_error_out);
end structural;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/ip_checksum.vhd
0,0 → 1,97
-------------------------------------------------------------------------------
-- Title : IP checksum counter
-- Project :
-------------------------------------------------------------------------------
-- File : ip_checksum.vhd
-- Author : Jussi Nieminen <niemin95@galapagosinkeiju.cs.tut.fi>
-- Company :
-- Last update: 2009/09/29
-- Platform :
-------------------------------------------------------------------------------
-- Description: Counts 1's complement checksum for IP header
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009/09/29 1.0 niemin95 Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.udp_ip_pkg.all;
 
entity ip_checksum is
 
generic (
-- this comes from the protocol, flags etc. field that are currently constants
pre_counted_part_g : std_logic_vector( ip_checksum_w_c-1 downto 0 ) := (others => '0')
);
 
port (
total_length_field_in : in std_logic_vector( 15 downto 0 );
source_addr_field_in : in std_logic_vector( ip_addr_w_c-1 downto 0 );
dest_addr_field_in : in std_logic_vector( ip_addr_w_c-1 downto 0 );
header_checksum_out : out std_logic_vector( ip_checksum_w_c-1 downto 0 )
);
 
end ip_checksum;
 
 
architecture rtl of ip_checksum is
 
-- currently we have 5 additions, which means that the overflowing part of
-- the additions can be at most 3-bits wide
constant middle_sum_w_c : integer := ip_checksum_w_c + 3;
signal middle_sum_int : integer range 0 to 2**middle_sum_w_c-1;
signal middle_sum_slv : std_logic_vector( middle_sum_w_c-1 downto 0 );
 
subtype addend_integer is integer range 0 to 2**ip_checksum_w_c-1;
signal length_int : addend_integer;
signal source_addr_high_int : addend_integer;
signal source_addr_low_int : addend_integer;
signal dest_addr_high_int : addend_integer;
signal dest_addr_low_int : addend_integer;
 
-------------------------------------------------------------------------------
begin -- rtl
-------------------------------------------------------------------------------
 
middle_sum_slv <= std_logic_vector( to_unsigned( middle_sum_int, middle_sum_w_c ));
 
length_int <= to_integer( unsigned( total_length_field_in ));
source_addr_high_int <= to_integer( unsigned( source_addr_field_in( ip_addr_w_c-1 downto 16 ) ));
source_addr_low_int <= to_integer( unsigned( source_addr_field_in( 15 downto 0 ) ));
dest_addr_high_int <= to_integer( unsigned( dest_addr_field_in( ip_addr_w_c-1 downto 16 ) ));
dest_addr_low_int <= to_integer( unsigned( dest_addr_field_in( 15 downto 0 ) ));
 
count_checksum : process (length_int, source_addr_high_int, source_addr_low_int,
dest_addr_high_int, dest_addr_low_int, middle_sum_slv)
variable middle_sum_v : std_logic_vector( ip_checksum_w_c downto 0 );
variable final_sum_v : integer range 0 to 2**ip_checksum_w_c - 1;
variable final_checksum_v : std_logic_vector( ip_checksum_w_c-1 downto 0 );
begin -- process count_checksum
 
middle_sum_int <= to_integer( unsigned( pre_counted_part_g ))+
length_int + source_addr_high_int + source_addr_low_int +
dest_addr_high_int + dest_addr_low_int;
 
middle_sum_v :=
std_logic_vector( to_unsigned(
to_integer( unsigned( middle_sum_slv( ip_checksum_w_c-1 downto 0 ) )) +
to_integer( unsigned( middle_sum_slv( middle_sum_w_c-1 downto ip_checksum_w_c ) )),
ip_checksum_w_c+1 ));
 
final_sum_v := to_integer( unsigned( middle_sum_v( ip_checksum_w_c-1 downto 0 ) )) +
to_integer( unsigned( middle_sum_v( ip_checksum_w_c downto ip_checksum_w_c ) ));
 
final_checksum_v := not std_logic_vector( to_unsigned( final_sum_v, ip_checksum_w_c ));
 
header_checksum_out <= final_checksum_v;
 
end process count_checksum;
 
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/vhd/udp_arp_data_mux.vhd
0,0 → 1,156
-------------------------------------------------------------------------------
-- Title : data mux
-- Project :
-------------------------------------------------------------------------------
-- File : udp_arp_data_mux.vhd
-- Author : Jussi Nieminen <niemin95@galapagosinkeiju.cs.tut.fi>
-- Last update: 2010-08-18
-------------------------------------------------------------------------------
-- Description: Multiplexer.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009/09/15 1.0 niemin95 Created
-------------------------------------------------------------------------------
 
 
 
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.udp_ip_pkg.all;
 
entity udp_arp_data_mux is
 
generic (
data_width_g : integer := 16;
tx_len_w_g : integer := 11
);
 
port (
rx_data_valid_in : in std_logic;
new_rx_in : in std_logic;
rx_data_in : in std_logic_vector( data_width_g-1 downto 0 );
rx_res_in : in std_logic_vector( 2 downto 0 );
rx_re_out : out std_logic;
rx_datas_out : out std_logic_vector( 3*data_width_g-1 downto 0 );
rx_data_valids_out : out std_logic_vector( 2 downto 0 );
new_rxs_out : out std_logic_vector( 1 downto 0 );
tx_datas_in : in std_logic_vector( 3*data_width_g-1 downto 0 );
tx_data_valids_in : in std_logic_vector( 2 downto 0 );
tx_target_MACs_in : in std_logic_vector( 2*MAC_addr_w_c-1 downto 0 );
tx_lens_in : in std_logic_vector( 2*tx_len_w_g-1 downto 0 );
tx_frame_types_in : in std_logic_vector( 2*frame_type_w_c-1 downto 0 );
new_txs_in : in std_logic_vector( 1 downto 0 );
tx_re_in : in std_logic;
tx_data_out : out std_logic_vector( data_width_g-1 downto 0 );
tx_data_valid_out : out std_logic;
tx_target_MAC_out : out std_logic_vector( MAC_addr_w_c-1 downto 0 );
tx_len_out : out std_logic_vector( tx_len_w_g-1 downto 0 );
tx_frame_type_out : out std_logic_vector( frame_type_w_c-1 downto 0 );
new_tx_out : out std_logic;
tx_res_out : out std_logic_vector( 2 downto 0 );
input_select_in : in std_logic_vector( 1 downto 0 );
output_select_in : in std_logic_vector( 1 downto 0 )
);
 
end udp_arp_data_mux;
 
 
architecture rtl of udp_arp_data_mux is
 
signal input_select_int : integer range 0 to 2;
signal output_select_int : integer range 0 to 2;
type tx_data_array is array (0 to 2) of std_logic_vector( udp_data_width_c-1 downto 0 );
signal rx_datas_array_r : tx_data_array;
signal tx_datas_array_r : tx_data_array;
 
type MAC_array is array (0 to 1) of std_logic_vector( MAC_addr_w_c-1 downto 0 );
signal MAC_addr_array_r : MAC_array;
type frame_type_array is array (0 to 1) of std_logic_vector( frame_type_w_c-1 downto 0 );
signal frame_type_array_r : frame_type_array;
type tx_lens_array is array (0 to 1) of std_logic_vector( tx_len_w_c-1 downto 0 );
signal tx_lens_array_r : tx_lens_array;
 
constant udp_selected_c : integer := 0;
constant arp_selected_c : integer := 1;
constant app_selected_c : integer := 2;
 
-------------------------------------------------------------------------------
begin -- rtl
-------------------------------------------------------------------------------
 
input_select_int <= to_integer( unsigned( input_select_in ));
output_select_int <= to_integer( unsigned( output_select_in ));
-- 0: UDP
-- 1: ARP
-- 2: application
 
datas: for n in 0 to 2 generate
rx_datas_out( (n+1)*udp_data_width_c-1 downto n*udp_data_width_c ) <= rx_datas_array_r(n);
tx_datas_array_r(n) <= tx_datas_in( (n+1)*udp_data_width_c-1 downto n*udp_data_width_c );
end generate datas;
 
other_arrays: for n in 0 to 1 generate
MAC_addr_array_r(n) <= tx_target_MACs_in( (n+1)*MAC_addr_w_c-1 downto n*MAC_addr_w_c );
frame_type_array_r(n) <= tx_frame_types_in( (n+1)*frame_type_w_c-1 downto n*frame_type_w_c );
tx_lens_array_r(n) <= tx_lens_in( (n+1)*tx_len_w_c-1 downto n*tx_len_w_c );
end generate other_arrays;
 
eth_data_mux : process (rx_data_in, rx_data_valid_in, new_rx_in, input_select_int,
output_select_int, rx_res_in, tx_datas_array_r, tx_data_valids_in,
MAC_addr_array_r, tx_lens_array_r, frame_type_array_r, new_txs_in,
tx_re_in)
begin -- process eth_data_mux
 
-- ** INPUTS **
-- default values. Others than the selected range stay as zero.
rx_datas_array_r <= (others => (others => '0'));
rx_data_valids_out <= (others => '0');
new_rxs_out <= (others => '0');
 
rx_datas_array_r(input_select_int) <= rx_data_in;
rx_data_valids_out( input_select_int ) <= rx_data_valid_in;
 
if input_select_int /= app_selected_c then
new_rxs_out( input_select_int ) <= new_rx_in;
else
-- if data is going to application, also the udp block needs to have the
-- data_valid signal (to know when reading really happens. Plain re from
-- application isn't enough, cause it can be up even if data_valid is down.)
rx_data_valids_out(udp_selected_c) <= rx_data_valid_in;
end if;
 
rx_re_out <= rx_res_in( input_select_int );
 
-- ** OUTPUTS **
tx_data_out <= tx_datas_array_r( output_select_int );
tx_data_valid_out <= tx_data_valids_in( output_select_int );
-- only data and data_valid can come from application, others come either
-- from arp or udp
if output_select_int /= app_selected_c then
tx_target_MAC_out <= MAC_addr_array_r( output_select_int );
tx_len_out <= tx_lens_array_r( output_select_int );
tx_frame_type_out <= frame_type_array_r( output_select_int );
new_tx_out <= new_txs_in( output_select_int );
else
-- if data is coming from the application, these signals have been set by
-- udp block
tx_target_MAC_out <= MAC_addr_array_r( udp_selected_c );
tx_len_out <= tx_lens_array_r( udp_selected_c );
tx_frame_type_out <= frame_type_array_r( udp_selected_c );
new_tx_out <= new_txs_in( udp_selected_c );
end if;
 
tx_res_out <= (others => '0');
tx_res_out( output_select_int ) <= tx_re_in;
 
end process eth_data_mux;
 
end rtl;
/funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/UDP_IP_documentation.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/UDP_IP_documentation.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/ethernet_conns_reference.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/ethernet_conns_reference.pdf =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/ethernet_conns_reference.pdf (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/ethernet_conns_reference.pdf (revision 34)
funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/doc/ethernet_conns_reference.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.absDef.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.absDef.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.absDef.1.0.xml (revision 34) @@ -0,0 +1,133 @@ + + + + TUT + ip.hwp.interface + udp_ip_tx_16bit.absDef + 1.0 + + + + fatal_error_out + When high, fatal error in ethernet controller. Application must reset. + + + required + 1 + out + + false + + + link_up_out + When high, link is established between the peers and operations are allowed. + + + required + 1 + out + + false + + + new_tx_in + Set this high simultaneously with tx_len, target_addr, target_port, source_port, first tx_data and tx_data_valid to initiate a new tx operation. Creating packet headers will take a few dozens clock cycles. Operation is acknowledged when the tx_re is asserted for the first word. + + + required + 1 + in + + false + + + no_arp_target_MAC_in + IF you have disabled ARP: Supply the destination MAC addres for TX operations + + + optional + 48 + in + + 0 + + + + source_port_in + Source IP port number for a new tx operation. + + + required + 16 + in + + false + + + target_addr_in + Destination IP address for a new tx operation + + + required + 32 + in + + false + + + target_port_in + Destination IP port number for a new tx operation + + + required + 16 + in + + false + + + tx_data_in + Data to be sent, one word at a time. The first data must be available when new_tx is asserted. + + + required + 16 + in + + false + + + tx_data_valid_in + Set this high simultaneously with the data input. + + + required + 1 + in + + false + + + tx_len_in + Length of packet payload for the new tx operation IN BYTES. + + + required + 11 + in + + false + + + tx_re_out + Acknowledges a read of tx_data. You can update the next word after this. + + + required + 1 + out + + false + + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.1.0.xml (revision 34) @@ -0,0 +1,1054 @@ + + + + TUT + ip.hwp.interface + udp_ip_lan91c111 + 1.0 + + + LAN91C111 + LAN91C111 + Connection to the LAN91C111 chip via IO pins. + + + + false + + + + eth_data_inout + + 31 + 0 + + + + eth_data_inout + + 31 + 0 + + + + + + eth_addr_out + + 14 + 0 + + + + eth_addr_out + + 14 + 0 + + + + + + eth_interrupt_in + + 0 + 0 + + + + eth_interrupt_in + + 0 + 0 + + + + + + eth_read_out + + 0 + 0 + + + + eth_read_out + + 0 + 0 + + + + + + eth_write_out + + 0 + 0 + + + + eth_write_out + + 0 + 0 + + + + + + eth_nADS_out + + 0 + 0 + + + + eth_nADS_out + + 0 + 0 + + + + + + eth_nAEN_out + + 0 + 0 + + + + eth_nAEN_out + + 0 + 0 + + + + + + eth_nBE_out + + 3 + 0 + + + + eth_nBE_out + + 3 + 0 + + + + + 8 + little + + + app_rx + app_rx + Application receive operations + + + + false + + + + new_rx_out + + 0 + 0 + + + + new_rx_out + + 0 + 0 + + + + + + rx_data_valid_out + + 0 + 0 + + + + rx_data_valid_out + + 0 + 0 + + + + + + rx_re_in + + 0 + 0 + + + + rx_re_in + + 0 + 0 + + + + + + rx_erroneous_out + + 0 + 0 + + + + rx_erroneous_out + + 0 + 0 + + + + + + source_addr_out + + 31 + 0 + + + + source_addr_out + + 31 + 0 + + + + + + source_port_out + + 15 + 0 + + + + source_port_out + + 15 + 0 + + + + + + dest_port_out + + 15 + 0 + + + + dest_port_out + + 15 + 0 + + + + + + rx_len_out + + 10 + 0 + + + + rx_len_out + + 10 + 0 + + + + + + rx_data_out + + 15 + 0 + + + + rx_data_out + + 15 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_out + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + + rx_error_out + + 0 + 0 + + + + rx_error_out + + 0 + 0 + + + + + 8 + little + + + app_tx + app_tx + Application transmit operations + + + + false + + + + new_tx_in + + 0 + 0 + + + + new_tx_in + + 0 + 0 + + + + + + tx_len_in + + 10 + 0 + + + + tx_len_in + + 10 + 0 + + + + + + target_addr_in + + 31 + 0 + + + + target_addr_in + + 31 + 0 + + + + + + target_port_in + + 15 + 0 + + + + target_port_in + + 15 + 0 + + + + + + source_port_in + + 15 + 0 + + + + source_port_in + + 15 + 0 + + + + + + tx_data_in + + 15 + 0 + + + + tx_data_in + + 15 + 0 + + + + + + tx_data_valid_in + + 0 + 0 + + + + tx_data_valid_in + + 0 + 0 + + + + + + tx_re_out + + 0 + 0 + + + + tx_re_out + + 0 + 0 + + + + + + no_arp_target_MAC_in + + 47 + 0 + + + + no_arp_target_MAC_in + + 47 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_out + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + 8 + little + + + clk + clk + Clock 25 MHz in. + + + + false + + + + CLK + + 0 + 0 + + + + clk + + 0 + 0 + + + + + 8 + little + + + rst_n + rst_n + Asynchronous reset active-low. + + + + false + + + + RESETn + + 0 + 0 + + + + rst_n + + 0 + 0 + + + + + 8 + little + + + + + + clk + + in + + 0 + 0 + + + + + dest_port_out + + out + + 15 + 0 + + + + + eth_addr_out + + out + + 14 + 0 + + + + + eth_data_inout + + inout + + 31 + 0 + + + + + eth_interrupt_in + + in + + 0 + 0 + + + + + eth_nADS_out + + out + + 0 + 0 + + + + + eth_nAEN_out + + out + + 0 + 0 + + + + + eth_nBE_out + + out + + 3 + 0 + + + + + eth_read_out + + out + + 0 + 0 + + + + + eth_write_out + + out + + 0 + 0 + + + + + fatal_error_out + + out + + 0 + 0 + + + + + link_up_out + + out + + 0 + 0 + + + + + new_rx_out + + out + + 0 + 0 + + + + + new_tx_in + + in + + 0 + 0 + + + + + no_arp_target_MAC_in + + in + + 47 + 0 + + + 0 + + + + + rst_n + + in + + 0 + 0 + + + + + rx_data_out + + out + + 15 + 0 + + + + + rx_data_valid_out + + out + + 0 + 0 + + + + + rx_erroneous_out + + out + + 0 + 0 + + + + + rx_error_out + + out + + + + rx_len_out + + out + + 10 + 0 + + + + + rx_re_in + + in + + 0 + 0 + + + + + source_addr_out + + out + + 31 + 0 + + + + + source_port_in + + in + + 15 + 0 + + + + + source_port_out + + out + + 15 + 0 + + + + + target_addr_in + + in + + 31 + 0 + + + + + target_port_in + + in + + 15 + 0 + + + + + tx_data_in + + in + + 15 + 0 + + + + + tx_data_valid_in + + in + + 0 + 0 + + + + + tx_len_in + + in + + 10 + 0 + + + + + tx_re_out + + out + + 0 + 0 + + + + + + + disable_arp_g + 0 + + + disable_rx_g + 0 + + + + + + HDLsources + HDL sources + HDL sources. + + ../vhd/udp_ip_pkg.vhd + vhdlSource + false + + false + + + + ../vhd/arp3.vhd + vhdlSource + false + + false + + + + ../vhd/arpsnd.vhd + vhdlSource + false + + false + + + + ../vhd/ip_checksum.vhd + vhdlSource + false + + false + + + + ../vhd/udp.vhd + vhdlSource + false + + false + + + + ../vhd/udp_arp_data_mux.vhd + vhdlSource + false + + false + + + + ../vhd/udp_ip.vhd + vhdlSource + false + + false + + + + ../vhd/udp_ip_lan91c111.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_send_module.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_comm_module.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_controller.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_ctrl_pkg.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_init_module.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_interrupt_handler.vhd + vhdlSource + false + + false + + + + ../../../eth_lan91c111_ctrl/1.0/vhd/lan91c111_read_module.vhd + vhdlSource + false + + false + + + + + UDP/IP and LAN91C111 controller. + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.1.0.xml (revision 34) @@ -0,0 +1,1054 @@ + + + + TUT + ip.hwp.interface + udp_ip_dm9000a + 1.0 + + + DM9000A + DM9000A + Connection to the DM9000A chip via IO pins. + + + + false + + + + eth_chip_sel_out + + 0 + 0 + + + + eth_chip_sel_out + + 0 + 0 + + + + + + eth_clk_out + + 0 + 0 + + + + eth_clk_out + + 0 + 0 + + + + + + eth_cmd_out + + 0 + 0 + + + + eth_cmd_out + + 0 + 0 + + + + + + eth_data_inout + + 15 + 0 + + + + eth_data_inout + + 15 + 0 + + + + + + eth_interrupt_in + + 0 + 0 + + + + eth_interrupt_in + + 0 + 0 + + + + + + eth_read_out + + 0 + 0 + + + + eth_read_out + + 0 + 0 + + + + + + eth_reset_out + + 0 + 0 + + + + eth_reset_out + + 0 + 0 + + + + + + eth_write_out + + 0 + 0 + + + + eth_write_out + + 0 + 0 + + + + + 8 + little + + + app_rx + app_rx + Application receive operations + + + + false + + + + new_rx_out + + 0 + 0 + + + + new_rx_out + + 0 + 0 + + + + + + rx_data_valid_out + + 0 + 0 + + + + rx_data_valid_out + + 0 + 0 + + + + + + rx_re_in + + 0 + 0 + + + + rx_re_in + + 0 + 0 + + + + + + rx_erroneous_out + + 0 + 0 + + + + rx_erroneous_out + + 0 + 0 + + + + + + source_addr_out + + 31 + 0 + + + + source_addr_out + + 31 + 0 + + + + + + source_port_out + + 15 + 0 + + + + source_port_out + + 15 + 0 + + + + + + dest_port_out + + 15 + 0 + + + + dest_port_out + + 15 + 0 + + + + + + rx_len_out + + 10 + 0 + + + + rx_len_out + + 10 + 0 + + + + + + rx_data_out + + 15 + 0 + + + + rx_data_out + + 15 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_out + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + + rx_error_out + + 0 + 0 + + + + rx_error_out + + 0 + 0 + + + + + 8 + little + + + app_tx + app_tx + Application transmit operations + + + + false + + + + new_tx_in + + 0 + 0 + + + + new_tx_in + + 0 + 0 + + + + + + tx_len_in + + 10 + 0 + + + + tx_len_in + + 10 + 0 + + + + + + target_addr_in + + 31 + 0 + + + + target_addr_in + + 31 + 0 + + + + + + target_port_in + + 15 + 0 + + + + target_port_in + + 15 + 0 + + + + + + source_port_in + + 15 + 0 + + + + source_port_in + + 15 + 0 + + + + + + tx_data_in + + 15 + 0 + + + + tx_data_in + + 15 + 0 + + + + + + tx_data_valid_in + + 0 + 0 + + + + tx_data_valid_in + + 0 + 0 + + + + + + tx_re_out + + 0 + 0 + + + + tx_re_out + + 0 + 0 + + + + + + no_arp_target_MAC_in + + 47 + 0 + + + + no_arp_target_MAC_in + + 47 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_out + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + 8 + little + + + clk + clk + Clock 25 MHz in. + + + + false + + + + CLK + + 0 + 0 + + + + clk + + 0 + 0 + + + + + 8 + little + + + rst_n + rst_n + Asynchronous reset active-low. + + + + false + + + + RESETn + + 0 + 0 + + + + rst_n + + 0 + 0 + + + + + 8 + little + + + + + + clk + + in + + 0 + 0 + + + + + dest_port_out + + out + + 15 + 0 + + + + + eth_chip_sel_out + + out + + 0 + 0 + + + + + eth_clk_out + + out + + 0 + 0 + + + + + eth_cmd_out + + out + + 0 + 0 + + + + + eth_data_inout + + inout + + 15 + 0 + + + + + eth_interrupt_in + + in + + 0 + 0 + + + + + eth_read_out + + out + + 0 + 0 + + + + + eth_reset_out + + out + + 0 + 0 + + + + + eth_write_out + + out + + 0 + 0 + + + + + fatal_error_out + + out + + 0 + 0 + + + + + link_up_out + + out + + 0 + 0 + + + + + new_rx_out + + out + + 0 + 0 + + + + + new_tx_in + + in + + 0 + 0 + + + + + no_arp_target_MAC_in + + in + + 47 + 0 + + + 0 + + + + + rst_n + + in + + 0 + 0 + + + + + rx_data_out + + out + + 15 + 0 + + + + + rx_data_valid_out + + out + + 0 + 0 + + + + + rx_erroneous_out + + out + + 0 + 0 + + + + + rx_error_out + + out + + + + rx_len_out + + out + + 10 + 0 + + + + + rx_re_in + + in + + 0 + 0 + + + + + source_addr_out + + out + + 31 + 0 + + + + + source_port_in + + in + + 15 + 0 + + + + + source_port_out + + out + + 15 + 0 + + + + + target_addr_in + + in + + 31 + 0 + + + + + target_port_in + + in + + 15 + 0 + + + + + tx_data_in + + in + + 15 + 0 + + + + + tx_data_valid_in + + in + + 0 + 0 + + + + + tx_len_in + + in + + 10 + 0 + + + + + tx_re_out + + out + + 0 + 0 + + + + + + + disable_arp_g + 0 + + + disable_rx_g + 0 + + + + + + HDLsources + HDL sources + HDL sources. + + ../vhd/udp_ip_pkg.vhd + vhdlSource + false + + false + + + + ../vhd/arp3.vhd + vhdlSource + false + + false + + + + ../vhd/arpsnd.vhd + vhdlSource + false + + false + + + + ../vhd/ip_checksum.vhd + vhdlSource + false + + false + + + + ../vhd/udp.vhd + vhdlSource + false + + false + + + + ../vhd/udp_arp_data_mux.vhd + vhdlSource + false + + false + + + + ../vhd/udp_ip.vhd + vhdlSource + false + + false + + + + ../vhd/udp_ip_dm9000a.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_send_module.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_comm_module.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_controller.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_ctrl_pkg.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_init_module.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_interrupt_handler.vhd + vhdlSource + false + + false + + + + ../../../eth_dm9000a_ctrl/1.0/vhd/DM9kA_read_module.vhd + vhdlSource + false + + false + + + + + DM9000A controller and UDP/IP. + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.1.0.xml (revision 34) @@ -0,0 +1,10 @@ + + + + TUT + ip.hwp.interface + udp_ip_rx_16bit + 1.0 + true + true + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_flood_example.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_flood_example.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_flood_example.1.0.xml (revision 34) @@ -0,0 +1,729 @@ + + + + TUT + ip.hwp.interface + simple_udp_flood_example + 1.0 + + + clk + clk + Clock 25 MHz synchronous to UDP/IP/ETH clock. + + + + false + + + + CLK + + 0 + 0 + + + + clk + + 0 + 0 + + + + + 8 + little + + + link_up_out + link_up_out + Connect a LED here; rises a few seconds after the autonegotiation process is done. + + + + false + + + + gpio_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + 8 + little + + + rst_n + rst_n + rst_n + + + + false + + + + RESETn + + 0 + 0 + + + + rst_n + + 0 + 0 + + + + + 8 + little + + + udp_ip_rx + udp_ip_rx + udp_ip_rx. Optional, this example does not receive anything. + + + + false + + + + new_rx_out + + 0 + 0 + + + + new_rx_in + + 0 + 0 + + + + + + rx_erroneous_out + + 0 + 0 + + + + rx_erroneous_in + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_in + + 0 + 0 + + + + + + dest_port_out + + 15 + 0 + + + + dest_port_in + + 15 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_in + + 0 + 0 + + + + + + rx_data_out + + 15 + 0 + + + + rx_data_in + + 15 + 0 + + + + + + rx_data_valid_out + + 0 + 0 + + + + rx_data_valid_in + + 0 + 0 + + + + + + rx_len_out + + 10 + 0 + + + + rx_len_in + + 10 + 0 + + + + + + rx_re_in + + 0 + 0 + + + + rx_re_out + + 0 + 0 + + + + + + source_addr_out + + 31 + 0 + + + + source_addr_in + + 31 + 0 + + + + + + source_port_out + + 15 + 0 + + + + source_port_in + + 15 + 0 + + + + + + rx_error_out + + 0 + 0 + + + + rx_error_in + + 0 + 0 + + + + + 8 + little + + + udp_ip_tx + udp_ip_tx + udp_ip_tx + + + + false + + + + new_tx_in + + 0 + 0 + + + + new_tx_out + + 0 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_in + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_in + + 0 + 0 + + + + + + no_arp_target_MAC_in + + 47 + 0 + + + + no_arp_target_MAC_out + + 47 + 0 + + + + + + tx_data_in + + 15 + 0 + + + + tx_data_out + + 15 + 0 + + + + + + tx_re_out + + 0 + 0 + + + + tx_re_in + + 0 + 0 + + + + + + tx_len_in + + 10 + 0 + + + + tx_len_out + + 10 + 0 + + + + + + tx_data_valid_in + + 0 + 0 + + + + tx_data_valid_out + + 0 + 0 + + + + + + target_port_in + + 15 + 0 + + + + target_port_out + + 15 + 0 + + + + + + target_addr_in + + 31 + 0 + + + + target_addr_out + + 31 + 0 + + + + + + source_port_in + + 15 + 0 + + + + source_port_out + + 15 + 0 + + + + + 8 + little + + + + + + clk + + in + + + + dest_port_in + + in + + 15 + 0 + + + + + fatal_error_in + + in + + + + link_up_in + + in + + + + link_up_out + + out + + + + new_rx_in + + in + + + + new_tx_out + + out + + + + no_arp_target_MAC_out + + out + + 47 + 0 + + + + + rst_n + + in + + + + rx_data_in + + in + + 15 + 0 + + + + + rx_data_valid_in + + in + + + + rx_erroneous_in + + in + + + + rx_error_in + + in + + + + rx_len_in + + in + + 10 + 0 + + + + + rx_re_out + + out + + + + source_addr_in + + in + + 31 + 0 + + + + + source_port_in + + in + + 15 + 0 + + + + + source_port_out + + out + + 15 + 0 + + + + + target_addr_out + + out + + 31 + 0 + + + + + target_port_out + + out + + 15 + 0 + + + + + tx_data_out + + out + + 15 + 0 + + + + + tx_data_valid_out + + out + + + + tx_len_out + + out + + 10 + 0 + + + + + tx_re_in + + in + + + + + + data_width_g + 16 + + + disable_arp_g + 0 + + + packet_len_g + 1000 + + + source_ip_port_g + 6000 + + + target_MAC_addr_g + x"ACDCABBACD01" + + + target_ip_addr_g + x"0A000001" + + + target_ip_port_g + 5000 + + + + + + HDLsources + HDL sources + VHDL sources + + ../vhd/simple_udp_flood_example.vhd + vhdlSource + false + + false + + + + + Connect to UDP/IP controller. Creates TX operations as quickly as possible. Destination and packet size are configurable by using generics. + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_receiver_example.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_receiver_example.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/simple_udp_receiver_example.1.0.xml (revision 34) @@ -0,0 +1,784 @@ + + + + TUT + ip.hwp.interface + simple_udp_receiver_example + 1.0 + + + clk + clk + 25 MHz clock synch with udp/ip ctrl. + + + + false + + + + CLK + + 0 + 0 + + + + clk + + 0 + 0 + + + + + 8 + little + + + led_out + led_out + Led that changes its state after each received packet. + + + + false + + + + gpio_out + + 0 + 0 + + + + led_out + + 0 + 0 + + + + + 8 + little + + + link_up_out + link_up_out + Connect a LED here; rises a few seconds after the autonegotiation process is done. + + + + false + + + + gpio_out + + 0 + 0 + + + + link_up_out + + 0 + 0 + + + + + 8 + little + + + rst_n + rst_n + rst_n + + + + false + + + + RESETn + + 0 + 0 + + + + rst_n + + 0 + 0 + + + + + 8 + little + + + udp_ip_rx + udp_ip_rx + udp_ip_rx + + + + false + + + + rx_error_out + + 0 + 0 + + + + rx_error_in + + 0 + 0 + + + + + + dest_port_out + + 15 + 0 + + + + dest_port_in + + 15 + 0 + + + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_in + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_in + + 0 + 0 + + + + + + new_rx_out + + 0 + 0 + + + + new_rx_in + + 0 + 0 + + + + + + rx_data_out + + 15 + 0 + + + + rx_data_in + + 15 + 0 + + + + + + rx_data_valid_out + + 0 + 0 + + + + rx_data_valid_in + + 0 + 0 + + + + + + rx_erroneous_out + + 0 + 0 + + + + rx_erroneous_in + + 0 + 0 + + + + + + rx_len_out + + 10 + 0 + + + + rx_len_in + + 10 + 0 + + + + + + rx_re_in + + 0 + 0 + + + + rx_re_out + + 0 + 0 + + + + + + source_addr_out + + 31 + 0 + + + + source_addr_in + + 31 + 0 + + + + + + source_port_out + + 15 + 0 + + + + source_port_in + + 15 + 0 + + + + + 8 + little + + + udp_ip_tx + udp_ip_tx + udp_ip_tx. Optional; this example does not send anything. + + + + false + + + + fatal_error_out + + 0 + 0 + + + + fatal_error_in + + 0 + 0 + + + + + + link_up_out + + 0 + 0 + + + + link_up_in + + 0 + 0 + + + + + + new_tx_in + + 0 + 0 + + + + new_tx_out + + 0 + 0 + + + + + + no_arp_target_MAC_in + + 47 + 0 + + + + no_arp_target_MAC_out + + 47 + 0 + + + + + + source_port_in + + 15 + 0 + + + + source_port_out + + 15 + 0 + + + + + + target_addr_in + + 31 + 0 + + + + target_addr_out + + 31 + 0 + + + + + + target_port_in + + 15 + 0 + + + + target_port_out + + 15 + 0 + + + + + + tx_data_in + + 15 + 0 + + + + tx_data_out + + 15 + 0 + + + + + + tx_data_valid_in + + 0 + 0 + + + + tx_data_valid_out + + 0 + 0 + + + + + + tx_len_in + + 10 + 0 + + + + tx_len_out + + 10 + 0 + + + + + + tx_re_out + + 0 + 0 + + + + tx_re_in + + 0 + 0 + + + + + 8 + little + + + + + + clk + + in + + 0 + 0 + + + + + dest_port_in + + in + + 15 + 0 + + + + + fatal_error_in + + in + + 0 + 0 + + + + + led_out + + out + + + + link_up_in + + in + + 0 + 0 + + + + + link_up_out + + out + + + + new_rx_in + + in + + 0 + 0 + + + + + new_tx_out + + out + + 0 + 0 + + + + + no_arp_target_MAC_out + + out + + 47 + 0 + + + + + rst_n + + in + + 0 + 0 + + + + + rx_data_in + + in + + 15 + 0 + + + + + rx_data_valid_in + + in + + 0 + 0 + + + + + rx_erroneous_in + + in + + 0 + 0 + + + + + rx_error_in + + in + + 0 + 0 + + + + + rx_len_in + + in + + 10 + 0 + + + + + rx_re_out + + out + + 0 + 0 + + + + + source_addr_in + + in + + 31 + 0 + + + + + source_port_in + + in + + 15 + 0 + + + + + source_port_out + + out + + 15 + 0 + + + + + target_addr_out + + out + + 31 + 0 + + + + + target_port_out + + out + + 15 + 0 + + + + + tx_data_out + + out + + 15 + 0 + + + + + tx_data_valid_out + + out + + 0 + 0 + + + + + tx_len_out + + out + + 10 + 0 + + + + + tx_re_in + + in + + 0 + 0 + + + + + + + + HDLsources + HDLsources + HDLsources + + ../vhd/simple_udp_receiver_example.vhd + vhdlSource + false + + false + + + + + Connect to UDP/IP controller. Receives all packets and blinks a LED as packets are received. Our own IP and MAC addresses are defined in udp_ip_pkg. + +If you decide to disable ARP, you have to manually add the FPGA MAC address to your PC's ARP table. + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_tx_16bit.1.0.xml (revision 34) @@ -0,0 +1,10 @@ + + + + TUT + ip.hwp.interface + udp_ip_tx_16bit + 1.0 + true + true + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.absDef.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.absDef.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_rx_16bit.absDef.1.0.xml (revision 34) @@ -0,0 +1,143 @@ + + + + TUT + ip.hwp.interface + udp_ip_rx_16bit.absDef + 1.0 + + + + rx_error_out + System error in ethernet controller. + + + optional + 1 + out + + false + + + dest_port_out + When new_rx = '1', this tells the destination IP port. + + + optional + 16 + out + + false + + + fatal_error_out + When high, fatal error in ethernet controller. Application must reset. + + + optional + 1 + out + + false + + + link_up_out + When high, link is established between the peers and operations are allowed. + + + optional + 1 + out + + false + + + new_rx_out + This is high when a new rx operation is completed and waiting. This is acknowledged by the first rx_re operation. + + + optional + 1 + out + + false + + + rx_data_out + 16 bits of RX data. Read this when rx_data_valid = '1' and acknowledge by issuing re = '1'. + + + optional + 16 + out + + false + + + rx_data_valid_out + If high, you can instantly read rx_data. + + + optional + 1 + out + + false + + + rx_erroneous_out + High, if the new rx operation was erroneous (e.g. CRC error) + + + optional + 1 + out + + false + + + rx_len_out + When new_rx = '1', this tells the size of the payload IN BYTES. You have to read ceil(rx_len_out/2) words. + + + optional + 11 + out + + false + + + rx_re_in + Acknowledge reading a word after rx_data_valid = '1' by asserting this high. + + + optional + 1 + in + + false + + + source_addr_out + When new_rx = '1', this tells the source IP address. + + + optional + 32 + out + + false + + + source_port_out + When new_rx = '1', this tells the source port. + + + optional + 16 + out + + false + + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.designcfg.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.designcfg.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.designcfg.1.0.xml (revision 34) @@ -0,0 +1,9 @@ + + + + TUT + ip.hwp.interface + udp_ip_dm9000a.designcfg + 1.0 + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.designcfg.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.designcfg.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.designcfg.1.0.xml (revision 34) @@ -0,0 +1,9 @@ + + + + TUT + ip.hwp.interface + udp_ip_lan91c111.designcfg + 1.0 + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.design.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.design.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_dm9000a.design.1.0.xml (revision 34) @@ -0,0 +1,9 @@ + + + + TUT + ip.hwp.interface + udp_ip_dm9000a.design + 1.0 + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.design.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.design.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/ip-xact/udp_ip_lan91c111.design.1.0.xml (revision 34) @@ -0,0 +1,9 @@ + + + + TUT + ip.hwp.interface + udp_ip_lan91c111.design + 1.0 + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_dm9000a_de2_assignments.qsf =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_dm9000a_de2_assignments.qsf (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_dm9000a_de2_assignments.qsf (revision 34) @@ -0,0 +1,31 @@ +set_location_assignment PIN_V2 -to rst_n_RESETn +set_location_assignment PIN_AE23 -to led_out_gpio_out +set_location_assignment PIN_AE22 -to link_up_out_gpio_out +set_location_assignment PIN_N2 -to clk_in_CLK +set_location_assignment PIN_D17 -to DM9000A_eth_data_inout[0] +set_location_assignment PIN_C17 -to DM9000A_eth_data_inout[1] +set_location_assignment PIN_B18 -to DM9000A_eth_data_inout[2] +set_location_assignment PIN_A18 -to DM9000A_eth_data_inout[3] +set_location_assignment PIN_B17 -to DM9000A_eth_data_inout[4] +set_location_assignment PIN_A17 -to DM9000A_eth_data_inout[5] +set_location_assignment PIN_B16 -to DM9000A_eth_data_inout[6] +set_location_assignment PIN_B15 -to DM9000A_eth_data_inout[7] +set_location_assignment PIN_B20 -to DM9000A_eth_data_inout[8] +set_location_assignment PIN_A20 -to DM9000A_eth_data_inout[9] +set_location_assignment PIN_C19 -to DM9000A_eth_data_inout[10] +set_location_assignment PIN_D19 -to DM9000A_eth_data_inout[11] +set_location_assignment PIN_B19 -to DM9000A_eth_data_inout[12] +set_location_assignment PIN_A19 -to DM9000A_eth_data_inout[13] +set_location_assignment PIN_E18 -to DM9000A_eth_data_inout[14] +set_location_assignment PIN_D18 -to DM9000A_eth_data_inout[15] +set_location_assignment PIN_B24 -to DM9000A_eth_clk_out +set_location_assignment PIN_A21 -to DM9000A_eth_cmd_out +set_location_assignment PIN_A23 -to DM9000A_eth_chip_sel_out +set_location_assignment PIN_B21 -to DM9000A_eth_interrupt_in +set_location_assignment PIN_A22 -to DM9000A_eth_read_out +set_location_assignment PIN_B22 -to DM9000A_eth_write_out +set_location_assignment PIN_B23 -to DM9000A_eth_reset_out + +set_global_assignment -name FAMILY "Cyclone II" +set_global_assignment -name DEVICE EP2C35F672C8 +set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" \ No newline at end of file Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_lan91c111_stratix2_s180_assignments.qsf =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_lan91c111_stratix2_s180_assignments.qsf (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/udp_ip_lan91c111_stratix2_s180_assignments.qsf (revision 34) @@ -0,0 +1,62 @@ +set_global_assignment -name FAMILY "Stratix II" +set_global_assignment -name DEVICE EP2S180F1020C3 +set_location_assignment PIN_AM17 -to clk_in_CLK +set_location_assignment PIN_AM27 -to LAN91C111_eth_addr_out[0] +set_location_assignment PIN_AM28 -to LAN91C111_eth_addr_out[1] +set_location_assignment PIN_AJ27 -to LAN91C111_eth_addr_out[2] +set_location_assignment PIN_AK27 -to LAN91C111_eth_addr_out[3] +set_location_assignment PIN_AL29 -to LAN91C111_eth_addr_out[4] +set_location_assignment PIN_AM29 -to LAN91C111_eth_addr_out[5] +set_location_assignment PIN_AJ28 -to LAN91C111_eth_addr_out[6] +set_location_assignment PIN_AH28 -to LAN91C111_eth_addr_out[7] +set_location_assignment PIN_AK20 -to LAN91C111_eth_addr_out[8] +set_location_assignment PIN_AJ20 -to LAN91C111_eth_addr_out[9] +set_location_assignment PIN_AJ21 -to LAN91C111_eth_addr_out[10] +set_location_assignment PIN_AL22 -to LAN91C111_eth_addr_out[11] +set_location_assignment PIN_AJ22 -to LAN91C111_eth_addr_out[12] +set_location_assignment PIN_AH22 -to LAN91C111_eth_addr_out[13] +set_location_assignment PIN_AL23 -to LAN91C111_eth_addr_out[14] +set_location_assignment PIN_AD18 -to LAN91C111_eth_data_inout[0] +set_location_assignment PIN_AB18 -to LAN91C111_eth_data_inout[1] +set_location_assignment PIN_AB19 -to LAN91C111_eth_data_inout[2] +set_location_assignment PIN_AC20 -to LAN91C111_eth_data_inout[3] +set_location_assignment PIN_AD20 -to LAN91C111_eth_data_inout[4] +set_location_assignment PIN_AE20 -to LAN91C111_eth_data_inout[5] +set_location_assignment PIN_AB20 -to LAN91C111_eth_data_inout[6] +set_location_assignment PIN_AF20 -to LAN91C111_eth_data_inout[7] +set_location_assignment PIN_AC21 -to LAN91C111_eth_data_inout[8] +set_location_assignment PIN_AD21 -to LAN91C111_eth_data_inout[9] +set_location_assignment PIN_AB21 -to LAN91C111_eth_data_inout[10] +set_location_assignment PIN_AE21 -to LAN91C111_eth_data_inout[11] +set_location_assignment PIN_AG20 -to LAN91C111_eth_data_inout[12] +set_location_assignment PIN_AF21 -to LAN91C111_eth_data_inout[13] +set_location_assignment PIN_AD22 -to LAN91C111_eth_data_inout[14] +set_location_assignment PIN_AF22 -to LAN91C111_eth_data_inout[15] +set_location_assignment PIN_AE22 -to LAN91C111_eth_data_inout[16] +set_location_assignment PIN_AC17 -to LAN91C111_eth_data_inout[17] +set_location_assignment PIN_AE19 -to LAN91C111_eth_data_inout[18] +set_location_assignment PIN_AD19 -to LAN91C111_eth_data_inout[19] +set_location_assignment PIN_AC18 -to LAN91C111_eth_data_inout[20] +set_location_assignment PIN_AB17 -to LAN91C111_eth_data_inout[21] +set_location_assignment PIN_AC19 -to LAN91C111_eth_data_inout[22] +set_location_assignment PIN_AL26 -to LAN91C111_eth_data_inout[23] +set_location_assignment PIN_AL27 -to LAN91C111_eth_data_inout[24] +set_location_assignment PIN_AL28 -to LAN91C111_eth_data_inout[25] +set_location_assignment PIN_AK28 -to LAN91C111_eth_data_inout[26] +set_location_assignment PIN_AK29 -to LAN91C111_eth_data_inout[27] +set_location_assignment PIN_AC13 -to LAN91C111_eth_data_inout[28] +set_location_assignment PIN_AD10 -to LAN91C111_eth_data_inout[29] +set_location_assignment PIN_AC11 -to LAN91C111_eth_data_inout[30] +set_location_assignment PIN_AE11 -to LAN91C111_eth_data_inout[31] +set_location_assignment PIN_AB23 -to LAN91C111_eth_interrupt_in +set_location_assignment PIN_AA25 -to LAN91C111_eth_nADS_out +set_location_assignment PIN_AC25 -to LAN91C111_eth_nAEN_out +set_location_assignment PIN_AE26 -to LAN91C111_eth_nBE_out[0] +set_location_assignment PIN_AE25 -to LAN91C111_eth_nBE_out[1] +set_location_assignment PIN_AD25 -to LAN91C111_eth_nBE_out[2] +set_location_assignment PIN_AD24 -to LAN91C111_eth_nBE_out[3] +set_location_assignment PIN_AC24 -to LAN91C111_eth_read_out +set_location_assignment PIN_AB26 -to LAN91C111_eth_write_out +set_location_assignment PIN_B4 -to link_up_out_gpio_out +set_location_assignment PIN_D5 -to led_out_gpio_out +set_location_assignment PIN_K14 -to rst_n_RESETn Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/readme.txt =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/readme.txt (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/udp_ip/1.0/syn/readme.txt (revision 34) @@ -0,0 +1,4 @@ +You can import these QSF files to Quartus when using the following boards: + +Altera DE2 with Davicom DM9000A +Altera Stratix II S180 DSP development board with SMSC LAN91C111 Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/vhd/ALTPLL_for_stratix2_100to25.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/vhd/ALTPLL_for_stratix2_100to25.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/vhd/ALTPLL_for_stratix2_100to25.vhd (revision 34) @@ -0,0 +1,376 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: ALTPLL_for_stratix2_100to25.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 9.1 Build 350 03/24/2010 SP 2 SJ Full Version +-- ************************************************************ + + +--Copyright (C) 1991-2010 Altera Corporation +--Your use of Altera Corporation's design tools, logic functions +--and other software and tools, and its AMPP partner logic +--functions, and any output files from any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Altera Program License +--Subscription Agreement, Altera MegaCore Function License +--Agreement, or other applicable license agreement, including, +--without limitation, that your use is for the sole purpose of +--programming logic devices manufactured by Altera and sold by +--Altera or its authorized distributors. Please refer to the +--applicable agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY altera_stratix2_pll_25 IS + PORT + ( + inclk0 : IN STD_LOGIC := '0'; + c0 : OUT STD_LOGIC + ); +END altera_stratix2_pll_25; + + +ARCHITECTURE SYN OF altera_stratix2_pll_25 IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL sub_wire1 : STD_LOGIC ; + SIGNAL sub_wire2_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire2 : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire3 : STD_LOGIC_VECTOR (5 DOWNTO 0); + SIGNAL sub_wire4_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire4 : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire7 : STD_LOGIC_VECTOR (3 DOWNTO 0); + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + compensate_clock : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + spread_frequency : NATURAL + ); + PORT ( + clkena : IN STD_LOGIC_VECTOR (5 DOWNTO 0); + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + extclkena : IN STD_LOGIC_VECTOR (3 DOWNTO 0); + clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + sub_wire2_bv(0 DOWNTO 0) <= "0"; + sub_wire2 <= To_stdlogicvector(sub_wire2_bv); + sub_wire4_bv(0 DOWNTO 0) <= "0"; + sub_wire4 <= NOT(To_stdlogicvector(sub_wire4_bv)); + sub_wire1 <= sub_wire0(0); + c0 <= sub_wire1; + sub_wire3 <= sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire4(0 DOWNTO 0); + sub_wire5 <= inclk0; + sub_wire6 <= sub_wire2(0 DOWNTO 0) & sub_wire5; + sub_wire7 <= sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0) & sub_wire2(0 DOWNTO 0); + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => 4, + clk0_duty_cycle => 50, + clk0_multiply_by => 1, + clk0_phase_shift => "0", + compensate_clock => "CLK0", + inclk0_input_frequency => 10000, + intended_device_family => "Stratix", + lpm_hint => "CBX_MODULE_PREFIX=ALTPLL_for_stratix2_100to25", + lpm_type => "altpll", + operation_mode => "NORMAL", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_UNUSED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_UNUSED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_UNUSED", + port_clk2 => "PORT_UNUSED", + port_clk3 => "PORT_UNUSED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + spread_frequency => 0 + ) + PORT MAP ( + clkena => sub_wire3, + inclk => sub_wire6, + extclkena => sub_wire7, + clk => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0" +-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0" +-- Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "9" +-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any" +-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "4" +-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "25.000000" +-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "100.000" +-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Stratix" +-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0" +-- Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0" +-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "300.000" +-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1" +-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0" +-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +-- Retrieval info: PRIVATE: SPREAD_USE STRING "0" +-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: USE_CLK0 STRING "1" +-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "4" +-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1" +-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "10000" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Stratix" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +-- Retrieval info: CONSTANT: SPREAD_FREQUENCY NUMERIC "0" +-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]" +-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]" +-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]" +-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +-- Retrieval info: CONNECT: @extclkena 0 0 1 1 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 4 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 1 GND 0 0 0 0 +-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +-- Retrieval info: CONNECT: @extclkena 0 0 1 2 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 5 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 2 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 0 VCC 0 0 0 0 +-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +-- Retrieval info: CONNECT: @extclkena 0 0 1 3 GND 0 0 0 0 +-- Retrieval info: CONNECT: @extclkena 0 0 1 0 GND 0 0 0 0 +-- Retrieval info: CONNECT: @clkena 0 0 1 3 GND 0 0 0 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25.ppf TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL ALTPLL_for_stratix2_100to25_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf +-- Retrieval info: CBX_MODULE_PREFIX: ON Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/ip-xact/altera_statix2_pll_25.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/ip-xact/altera_statix2_pll_25.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/altera_statix2_pll_25/ip-xact/altera_statix2_pll_25.1.0.xml (revision 34) @@ -0,0 +1,100 @@ + + + + TUT + ip.hwp.misc + altera_stratix2_pll_25 + 1.0 + + + clk_in + clk_in + Input clock (100 MHz, StratixII S180 board PIN_AM17) + + + + false + + + + CLK + + 0 + 0 + + + + inclk0 + + 0 + 0 + + + + + 8 + little + + + clk_out + clk_out + Output clock: input clock divided by 4. + + + + false + + + + CLK + + 0 + 0 + + + + c0 + + 0 + 0 + + + + + 8 + little + + + + + + c0 + + out + + + + inclk0 + + in + + + + + + + HDLsources + HDL sources + HDL sources. + + ../vhd/ALTPLL_for_stratix2_100to25.vhd + vhdlSource + false + + false + + + + + 25 MHz Altera ALTPLL instantiation for Stratix II FPGA's with input clk of 100 MHz (mul = 1, div = 4) + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.1.0.xml (revision 34) @@ -0,0 +1,10 @@ + + + + TUT + ip.hwp.interface + gpio_1bit + 1.0 + true + true + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.absDef.1.0.xml =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.absDef.1.0.xml (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/gpio_1bit/1.0/gpio_1bit.absDef.1.0.xml (revision 34) @@ -0,0 +1,31 @@ + + + + TUT + ip.hwp.interface + gpio_1bit.absDef + 1.0 + + + + gpio_out + + + required + 1 + out + + + required + 1 + out + + + required + 1 + out + + true + + + Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_send_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_send_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_send_module.vhd (revision 34) @@ -0,0 +1,441 @@ +------------------------------------------------------------------------------- +-- Title : DM9kA controller, sender module +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_send_module.vhd +-- Author : Jussi Nieminen +-- Last update: 2009/10/16 +------------------------------------------------------------------------------- +-- Description: Handles sending procedures +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/25 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.DM9kA_ctrl_pkg.all; + + +entity DM9kA_send_module is + + port ( + clk : in std_logic; + rst_n : in std_logic; + -- from interrupt handler + tx_completed_in : in std_logic; + -- to and from comm module + comm_req_out : out std_logic; + comm_grant_in : in std_logic; + reg_addr_out : out std_logic_vector( 7 downto 0 ); + config_data_out : out std_logic_vector( 7 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic; + -- to comm module + tx_data_out : out std_logic_vector( data_width_c-1 downto 0 ); + tx_data_valid_out : out std_logic; + tx_re_in : in std_logic; + -- from upper level + tx_data_in : in std_logic_vector( data_width_c-1 downto 0 ); + tx_data_valid_in : in std_logic; + tx_re_out : out std_logic; + tx_MAC_addr_in : in std_logic_vector( 47 downto 0 ); + new_tx_in : in std_logic; + tx_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 ); + tx_frame_type_in : in std_logic_vector( 15 downto 0 ) + ); + +end DM9kA_send_module; + + +architecture rtl of DM9kA_send_module is + + -- not much to initialize, but our own MAC we must get + type init_state_type is (get_MAC, done); + signal init_state_r : init_state_type; + + type conf_state_type is (write_conf, read_reply, wait_busy); + signal conf_state_r : conf_state_type; + + -- counter used when getting the MAC address + signal addr_cnt_r : integer range 0 to MAC_len_c-1; + + -- vhdl doesn't understand signals indexing std_logic_vectors, so we have to + -- do this: + type MAC_addr_type is array (0 to MAC_len_c-1) of std_logic_vector( 7 downto 0 ); + + signal own_MAC_r : MAC_addr_type; + signal trgt_MAC_r : MAC_addr_type; + + type tx_state_type is (wait_tx, conf_len_hi, conf_len_lo, conf_tx_reg, + write_trgt_MAC, write_own_MAC, write_frame_type, + count_data, send_cmd); + signal tx_state_r : tx_state_type; + + signal tx_len_r : std_logic_vector( tx_len_w_c-1 downto 0 ); + signal tx_len_int : integer range 0 to 2**tx_len_w_c-1; + signal tx_data_cnt_r : integer range 0 to 2**tx_len_w_c-1; + + signal tx_data_r : std_logic_vector( data_width_c-1 downto 0 ); + signal tx_data_valid_r : std_logic; + + signal comm_req_r : std_logic; + signal start_counting_r : std_logic; + + -- there can be maximum of 2 transfers at a time + signal tx_count_r : integer range 0 to 2; + + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + + -- switch between inner registers and data input + tx_data_mux: process (tx_data_in, tx_data_valid_in, tx_state_r, + tx_data_r, tx_data_valid_r, tx_re_in) + begin -- process tx_data_mux + + if tx_state_r /= count_data then + -- writing ethernet frame headers + tx_data_out <= tx_data_r; + tx_data_valid_out <= tx_data_valid_r; + -- no re to upper level + tx_re_out <= '0'; + + else + -- writing payload + tx_data_out <= tx_data_in; + tx_data_valid_out <= tx_data_valid_in; + tx_re_out <= tx_re_in; + + end if; + end process tx_data_mux; + + comm_req_out <= comm_req_r; + tx_len_int <= to_integer( unsigned( tx_len_r )); + + + main: process (clk, rst_n) + + -- helping with odd length transfers + variable odd_len_compensation_v : integer range 0 to 1; + + begin -- process main + if rst_n = '0' then -- asynchronous reset (active low) + + init_state_r <= get_MAC; + tx_state_r <= wait_tx; + conf_state_r <= write_conf; + + own_MAC_r <= (others => (others => '0')); + trgt_MAC_r <= (others => (others => '0')); + addr_cnt_r <= 0; + + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + config_valid_out <= '0'; + read_not_write_out <= '0'; + + comm_req_r <= '0'; + tx_data_r <= (others => '0'); + tx_data_valid_r <= '0'; + tx_len_r <= (others => '0'); + start_counting_r <= '0'; + tx_count_r <= 0; + + elsif clk'event and clk = '1' then -- rising clock edge + + -- decrease counter when a tx is completed + if tx_completed_in = '1' then + tx_count_r <= tx_count_r - 1; + end if; + + + + case init_state_r is + ----------------------------------------------------------------------- + -- Getting our own MAC address + when get_MAC => + + comm_req_r <= '1'; + + if comm_grant_in = '1' then + -- sender has comm modules attention + + case conf_state_r is + when write_conf => + + -- MAC address is in registers x'10 -> x'15 + reg_addr_out <= std_logic_vector( unsigned( MAC6_c ) - to_unsigned( addr_cnt_r, 8 )); + read_not_write_out <= '1'; + config_valid_out <= '1'; + + -- when busy comes up, comm module has started working + if comm_busy_in = '1' then + conf_state_r <= read_reply; + end if; + + when read_reply => + + if data_from_comm_valid_in = '1' then + own_MAC_r( addr_cnt_r ) <= data_from_comm_in( 7 downto 0 ); + conf_state_r <= wait_busy; + end if; + + when wait_busy => + + if comm_busy_in = '0' then + + if addr_cnt_r = MAC_len_c-1 then + init_state_r <= done; + addr_cnt_r <= 0; + comm_req_r <= '0'; + config_valid_out <= '0'; + else + addr_cnt_r <= addr_cnt_r + 1; + end if; + conf_state_r <= write_conf; + + end if; + when others => null; + end case; + end if; + ----------------------------------------------------------------------- + -- MAC address received, moving on + + when done => + -- init done, meaning normal operation + + -- new_tx_in, tx_len_in and tx_MAC_addr_in must remain stable until + -- the first data is read from the upper level. + + -- tx state machine + case tx_state_r is + when wait_tx => + + -- new transfer waiting, and less than 2 on the way + if new_tx_in = '1' and tx_count_r /= 2 then + -- add here checking of number of on-going txs + + comm_req_r <= '1'; + tx_len_r <= std_logic_vector( unsigned( tx_len_in ) + to_unsigned( eth_header_len_c, tx_len_w_c )); + + for n in 0 to MAC_len_c-1 loop + trgt_MAC_r(n) <= tx_MAC_addr_in( (n+1)*8-1 downto n*8 ); + end loop; -- n + + if comm_grant_in = '1' and comm_req_r = '1' then + -- increase number of txs + tx_count_r <= tx_count_r + 1; + tx_state_r <= conf_len_hi; + end if; + end if; + + when conf_len_hi => + + -- write high part of the tx len + case conf_state_r is + when write_conf => + + reg_addr_out <= TXPLH_c; + -- upper bits remain zero while lower ones get the values of + -- higher tx len bits + config_data_out <= (others => '0'); + config_data_out( tx_len_w_c-8-1 downto 0 ) <= tx_len_r( tx_len_w_c-1 downto 8 ); + read_not_write_out <= '0'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + conf_state_r <= wait_busy; + end if; + + when wait_busy => + + if comm_busy_in = '0' then + config_valid_out <= '0'; + conf_state_r <= write_conf; + tx_state_r <= conf_len_lo; + end if; + + when others => null; + end case; + + when conf_len_lo => + + -- write lower part of the tx len + case conf_state_r is + when write_conf => + + reg_addr_out <= TXPLL_c; + config_data_out <= tx_len_r( 7 downto 0 ); + read_not_write_out <= '0'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + conf_state_r <= wait_busy; + end if; + + when wait_busy => + + if comm_busy_in = '0' then + config_valid_out <= '0'; + conf_state_r <= write_conf; + tx_state_r <= conf_tx_reg; + end if; + + when others => null; + end case; + + + when conf_tx_reg => + + -- when the address of tx register is written, comm module + -- automagically switches to tx mode and starts receiving tx data + -- until config_valid_out signal is lowered. + + reg_addr_out <= tx_data_reg_c; + read_not_write_out <= '0'; + config_valid_out <= '1'; + + -- when comm busy, move to send phase + if comm_busy_in = '1' then + tx_state_r <= write_trgt_MAC; + addr_cnt_r <= 0; + end if; + + + when write_trgt_MAC => + + -- write two bytes of address at once (MSB first) + tx_data_r <= trgt_MAC_r( MAC_len_c - 2*addr_cnt_r - 2 ) + & trgt_MAC_r( MAC_len_c - 2*addr_cnt_r - 1 ); + tx_data_valid_r <= '1'; + + -- when comm reads, increase counter or move on + if tx_re_in = '1' then + if addr_cnt_r = MAC_len_c/2 - 1 then + tx_data_valid_r <= '0'; + addr_cnt_r <= 0; + tx_state_r <= write_own_MAC; + else + addr_cnt_r <= addr_cnt_r + 1; + end if; + end if; + + + when write_own_MAC => + + tx_data_r <= own_MAC_r( MAC_len_c - 2*addr_cnt_r - 2 ) + & own_MAC_r( MAC_len_c - 2*addr_cnt_r - 1 ); + tx_data_valid_r <= '1'; + + -- when comm reads, increase counter or move on + if tx_re_in = '1' then + if addr_cnt_r = MAC_len_c/2 - 1 then + tx_data_valid_r <= '0'; + addr_cnt_r <= 0; + tx_state_r <= write_frame_type; + else + addr_cnt_r <= addr_cnt_r + 1; + end if; + end if; + + + when write_frame_type => + + tx_data_r <= tx_frame_type_in( 7 downto 0 ) & tx_frame_type_in( 15 downto 8 ); + tx_data_valid_r <= '1'; + + if tx_re_in = '1' then + -- the tx_data mux now switches the output, so we can clear + -- these registers + tx_data_r <= (others => '0'); + tx_data_valid_r <= '0'; + tx_data_cnt_r <= 0; + start_counting_r <= '1'; + end if; + + -- delay, so that changing input of tx_re_out doesn't cause a glitch + if start_counting_r = '1' then + tx_data_r <= (others => '0'); + tx_data_valid_r <= '0'; + tx_data_cnt_r <= 0; + start_counting_r <= '0'; + tx_state_r <= count_data; + end if; + + + when count_data => + -- data comes straight from the upper level, just count how much + -- has been sent and stop the transmission in time + + if tx_re_in = '1' then + + -- tx len in bytes but writing words, that's why the division + -- by two + odd_len_compensation_v := to_integer( unsigned( tx_len_r(0 downto 0) )); + if tx_data_cnt_r = ( tx_len_int - eth_header_len_c ) / 2 - 1 + odd_len_compensation_v then + -- All sent. Notify the comm module by lowering the config_valid_out + config_valid_out <= '0'; + tx_data_cnt_r <= 0; + + -- request send if constant says so (if DM9kA is configured + -- to start sending in advance, there is no need to raise the + -- tx request bit) + if send_cmd_en_c = 1 then + tx_state_r <= send_cmd; + else + tx_state_r <= wait_tx; + comm_req_r <= '0'; + end if; + + else + tx_data_cnt_r <= tx_data_cnt_r + 1; + end if; + end if; + + + when send_cmd => + + -- feed in send cmd + case conf_state_r is + when write_conf => + + reg_addr_out <= TCR_c; + -- start tx + config_data_out <= x"01"; + read_not_write_out <= '0'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + conf_state_r <= wait_busy; + end if; + + when wait_busy => + + if comm_busy_in = '0' then + config_valid_out <= '0'; + conf_state_r <= write_conf; + tx_state_r <= wait_tx; + comm_req_r <= '0'; + end if; + + when others => null; + end case; + + + when others => null; + end case; -- tx_state_r + when others => null; + end case; -- init_state_r + end if; + end process main; + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_comm_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_comm_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_comm_module.vhd (revision 34) @@ -0,0 +1,421 @@ +------------------------------------------------------------------------------- +-- Title : Communication module for the DM9000A controller block +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_comm_module.vhd +-- Author : Jussi Nieminen +-- Last update: 2009/12/21 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/21 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.DM9kA_ctrl_pkg.all; + +entity DM9kA_comm_module is + + port ( + clk : in std_logic; -- 25 MHz + rst_n : in std_logic; + comm_requests_in : in std_logic_vector( submodules_c-1 downto 0 ); + comm_grants_out : out std_logic_vector( submodules_c-1 downto 0 ); + interrupt_out : out std_logic; + tx_data_in : in std_logic_vector( data_width_c-1 downto 0 ); + tx_data_valid_in : in std_logic; + tx_re_out : out std_logic; + rx_data_out : out std_logic_vector( data_width_c-1 downto 0 ); + rx_data_valid_out : out std_logic; + rx_re_in : in std_logic; + init_ready_in : in std_logic; + init_sleep_time_in : in std_logic_vector( sleep_time_w_c-1 downto 0 ); + -- interface to submodules (and to init block) + register_addrs_in : in std_logic_vector( (submodules_c+1) * 8 - 1 downto 0 ); -- from each submodule + config_datas_in : in std_logic_vector( (submodules_c+1) * 8 - 1 downto 0 ); + read_not_write_in : in std_logic_vector( submodules_c downto 0 ); + configs_valid_in : in std_logic_vector( submodules_c downto 0 ); + data_to_submodules_out : out std_logic_vector( data_width_c - 1 downto 0 ); + data_to_sb_valid_out : out std_logic; + busy_to_submodules_out : out std_logic; + -- interface to DM9000A + eth_data_inout : inout std_logic_vector( data_width_c-1 downto 0 ); + eth_clk_out : out std_logic; + eth_cmd_out : out std_logic; + eth_chip_sel_out : out std_logic; + eth_interrupt_in : in std_logic; + eth_read_out : out std_logic; + eth_write_out : out std_logic; + eth_reset_out : out std_logic + ); + +end DM9kA_comm_module; + + +architecture rtl of DM9kA_comm_module is + + -- WRITING PROCEDURES + -- *** Step 1, register address + -- * cmd '0' means writing a configuration register address + -- * address is byte wide, so upper bits of data are meaningless + -- + -- *** Step 2, wait for at least a cycle + -- * write signal must be up at least a cycle after writing the address + -- + -- *** Step 3, the data + -- * cmd '1' means that we write to the register selected in step 1 + -- * we can also read the value by pulling down read instead of write + -- + -- *** Step 4, read if necessary + -- * if reading, read the value here, else, just do nothing + -- + -- *** Step 5, another pause + -- * DM9000A needs a delay of at least 2 cycles after writing to + -- a configuration register + -- + -- *** Step 6 (optional), sleep + -- * sometimes the DM9000A needs a bit more time to do something, + -- e.g. when PHY is started, it needs time to become fully functional + + type comm_state_type is (config, write_data, read_data); + signal comm_state_r : comm_state_type; + + type conf_state_type is (wait_valid, addr, pause1, write_conf, read_conf, pause2, pause3, sleep); + signal conf_state_r : conf_state_type; + + + -- Arbiter side selects one of the incoming communication requests and feeds + -- data to these: + signal register_addr : std_logic_vector( 7 downto 0 ); + signal config_data : std_logic_vector( 7 downto 0 ); + signal read_not_write : std_logic; -- 1 = read, 0 = write + signal config_valid : std_logic; + + signal comm_grants_r : std_logic_vector( submodules_c-1 downto 0 ); + + signal tx_data_coming_r : std_logic; + signal rx_data_coming_r : std_logic; + signal sleep_cnt_r : integer; + + signal tx_re_r : std_logic; + signal rx_data_valid_r : std_logic; + signal eth_read_r : std_logic; + + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + -- concurrent assignments + comm_grants_out <= comm_grants_r; + interrupt_out <= eth_interrupt_in; + eth_chip_sel_out <= '0'; + eth_clk_out <= clk; + eth_reset_out <= rst_n; + eth_read_out <= eth_read_r; + rx_data_valid_out <= rx_data_valid_r; + tx_re_out <= tx_re_r; + + arbitration: process (clk, rst_n) + variable reserved_v : std_logic; + begin -- process arbitration + if rst_n = '0' then -- asynchronous reset (active low) + + comm_grants_r <= (others => '0'); + + elsif clk'event and clk = '1' then -- rising clock edge + + reserved_v := '0'; + + if init_ready_in = '1' then + -- can't use 'others' in comparison, so we do it this way + if comm_grants_r = std_logic_vector( to_unsigned( 0, submodules_c )) then + + -- no one is using comm_module right now + -- lowest index wins + for n in 0 to submodules_c-1 loop + if comm_requests_in(n) = '1' then + if reserved_v = '0' then + comm_grants_r(n) <= '1'; + reserved_v := '1'; + end if; + end if; + end loop; -- n + + else + + -- clear grant when request goes out + for n in 0 to submodules_c-1 loop + if comm_grants_r(n) = '1' and comm_requests_in(n) = '0' then + comm_grants_r(n) <= '0'; + end if; + end loop; -- n + + end if; + + else + -- no grants during initialization + comm_grants_r <= (others => '0'); + end if; + + end if; + end process arbitration; + + + submodule_mux: process (comm_grants_r, register_addrs_in, config_datas_in, + read_not_write_in, configs_valid_in, init_ready_in) + begin -- process submodule_mux + + if init_ready_in = '0' then + + -- init block has the highest index, but it doesn't compete for it's turn + register_addr <= register_addrs_in( (submodules_c+1)*8 - 1 downto submodules_c*8 ); + config_data <= config_datas_in( (submodules_c+1)*8 - 1 downto submodules_c*8 ); + read_not_write <= read_not_write_in( submodules_c ); + config_valid <= configs_valid_in( submodules_c ); + + else + -- init ready, normal arbitration + + -- default: + register_addr <= (others => '0'); + config_data <= (others => '0'); + read_not_write <= '0'; + config_valid <= '0'; + + -- grant signal decides + for n in 0 to submodules_c-1 loop + + if comm_grants_r(n) = '1' then + register_addr <= register_addrs_in( (n+1)*8 - 1 downto n*8 ); + config_data <= config_datas_in( (n+1)*8 - 1 downto n*8 ); + read_not_write <= read_not_write_in(n); + config_valid <= configs_valid_in(n); + end if; + end loop; -- n + end if; + + end process submodule_mux; + + + DM9kA_communication: process (clk, rst_n) + begin -- process DM9kA_communication + if rst_n = '0' then -- asynchronous reset (active low) + + eth_write_out <= '1'; + eth_read_r <= '1'; + eth_data_inout <= (others => 'Z'); + eth_cmd_out <= '0'; + + data_to_submodules_out <= (others => '0'); + data_to_sb_valid_out <= '0'; + busy_to_submodules_out <= '0'; + + tx_data_coming_r <= '0'; + rx_data_coming_r <= '0'; + sleep_cnt_r <= 0; + + tx_re_r <= '0'; + rx_data_valid_r <= '0'; + + rx_data_out <= (others => '0'); + + elsif clk'event and clk = '1' then -- rising clock edge + + -- defaults: + eth_write_out <= '1'; -- remember, active low + eth_read_r <= '1'; + data_to_sb_valid_out <= '0'; -- this is active high + + case comm_state_r is + when config => + + case conf_state_r is + when wait_valid => + + busy_to_submodules_out <= '0'; + + if config_valid = '1' then + conf_state_r <= addr; + busy_to_submodules_out <= '1'; + end if; + + when addr => + + -- cmd tells the chip that register address coming + eth_cmd_out <= '0'; + -- and here comes the address + eth_data_inout <= x"00" & register_addr; + -- remember, write and read are active low + eth_write_out <= '0'; + + -- check if we are planning to start writing/reading tx/rx data + if register_addr = tx_data_reg_c then + conf_state_r <= pause3; + tx_data_coming_r <= '1'; + elsif register_addr = rx_data_reg_c then + conf_state_r <= pause3; + rx_data_coming_r <= '1'; + else + conf_state_r <= pause1; + end if; + + + when pause1 => + + -- just 1 clk cycle pause, required by the device + conf_state_r <= write_conf; + + + when write_conf => + + if read_not_write = '1' then + -- next we read + eth_data_inout <= (others => 'Z'); + eth_read_r <= '0'; + conf_state_r <= read_conf; + else + eth_data_inout <= x"00" & config_data; + eth_write_out <= '0'; + conf_state_r <= pause2; + end if; + + eth_cmd_out <= '1'; + + + when read_conf => + + data_to_submodules_out <= eth_data_inout; + data_to_sb_valid_out <= '1'; + conf_state_r <= pause2; + + + when pause2 => + -- DM9kA needs 2 clk cycles after writing/reading to/from data register + conf_state_r <= pause3; + + if init_ready_in = '1' or + init_sleep_time_in = std_logic_vector( to_unsigned( 0, sleep_time_w_c )) + then + -- lower busy already here to reduce delays with arbitration + -- (submodules clear their request signals once busy is down) + busy_to_submodules_out <= '0'; + end if; + + + when pause3 => + + -- if initializing, we might sleep for a while + if init_ready_in = '0' and + init_sleep_time_in /= std_logic_vector( to_unsigned( 0, sleep_time_w_c )) + then + conf_state_r <= sleep; + else + -- ok, done with this waiting, back to business + conf_state_r <= wait_valid; + + -- if reg addr was either for tx data or rx data + if tx_data_coming_r = '1' then + comm_state_r <= write_data; + elsif rx_data_coming_r = '1' then + eth_data_inout <= (others => 'Z'); + comm_state_r <= read_data; + end if; + + -- clear both registers + tx_data_coming_r <= '0'; + rx_data_coming_r <= '0'; + end if; + + + when sleep => + + if sleep_cnt_r = to_integer( unsigned( init_sleep_time_in )) then + sleep_cnt_r <= 0; + conf_state_r <= wait_valid; + elsif sleep_cnt_r = to_integer( unsigned( init_sleep_time_in )) - 1 then + -- lower busy once cycle earlier + busy_to_submodules_out <= '0'; + sleep_cnt_r <= sleep_cnt_r + 1; + else + sleep_cnt_r <= sleep_cnt_r + 1; + end if; + + when others => null; + end case; + + + when write_data => + + -- write data until send submodule lowers the config_valid signal + if config_valid = '1' then + + if tx_data_valid_in = '1' and tx_re_r = '0' then + tx_re_r <= '1'; + end if; + + if tx_re_r = '1' then + + tx_re_r <= '0'; + eth_cmd_out <= '1'; + eth_data_inout <= tx_data_in; + eth_write_out <= '0'; + + end if; + + else + -- all written + comm_state_r <= config; + end if; + + when read_data => + + eth_cmd_out <= '1'; + + -- Read data until read submodule lowers the config_valid signal. + -- DM9kA needs 1 clk cycle time after every read signal, so receiving + -- block can get data every second cycle. + if config_valid = '1' or rx_data_valid_r = '1' then + + -- remember, eth_read_r is active low + if rx_data_valid_r = '0' and eth_read_r = '1' then + eth_read_r <= '0'; + end if; + + if eth_read_r = '0' then + rx_data_out <= eth_data_inout; + rx_data_valid_r <= '1'; + end if; + + if rx_re_in = '1' and rx_data_valid_r = '1' then + rx_data_valid_r <= '0'; + + if config_valid = '1' then + eth_read_r <= '0'; + end if; + end if; + + else + -- all read + eth_cmd_out <= '0'; + comm_state_r <= config; + end if; + + when others => null; + end case; + end if; + end process DM9kA_communication; + + + + + + + + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_read_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_read_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_read_module.vhd (revision 34) @@ -0,0 +1,372 @@ +------------------------------------------------------------------------------- +-- Title : DM9kA controller, read module +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_read_module.vhd +-- Author : Jussi Nieminen +-- Last update: 2010/01/06 +------------------------------------------------------------------------------- +-- Description: Handles reading of rx data from DM9kA +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/09/02 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.DM9kA_ctrl_pkg.all; + + +entity DM9kA_read_module is + + port ( + clk : in std_logic; + rst_n : in std_logic; + -- from interrupt handler + rx_waiting_in : in std_logic; + -- from/to comm module + rx_data_in : in std_logic_vector( data_width_c-1 downto 0 ); + rx_data_valid_in : in std_logic; + rx_re_out : out std_logic; + reg_addr_out : out std_logic_vector( 7 downto 0 ); + config_data_out : out std_logic_vector( 7 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic; + comm_req_out : out std_logic; + comm_grant_in : in std_logic; + -- from/to upper level + rx_data_out : out std_logic_vector( data_width_c-1 downto 0 ); + rx_data_valid_out : out std_logic; + rx_re_in : in std_logic; + new_rx_out : out std_logic; + rx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 ); + frame_type_out : out std_logic_vector( 15 downto 0 ); + rx_erroneous_out : out std_logic; + fatal_error_out : out std_logic -- worse than some network error + ); + +end DM9kA_read_module; + + +architecture rtl of DM9kA_read_module is + + type read_state_type is (wait_rx, peek_first_byte, delay, prepare_comm, + check_first_byte, check_status, get_length, + strip_header, relay_data, strip_checksum1, + strip_checksum2, check_next, clear_interrupt, fatal_error); + signal state_r : read_state_type; + + signal comm_req_r : std_logic; + signal rx_re_r : std_logic; + signal rx_status_r : std_logic_vector( 7 downto 0 ); + + signal rx_len_r : integer range 0 to 2**tx_len_w_c-1; + signal delay_done_r : std_logic; + signal header_cnt_r : integer range 0 to 6; + signal clear_interrupt_r : std_logic; + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + + mux: process (rx_data_in, rx_data_valid_in, rx_re_in, rx_re_r, state_r) + begin -- process mux + + if state_r = relay_data then + + rx_data_out <= rx_data_in; + rx_data_valid_out <= rx_data_valid_in; + rx_re_out <= rx_re_in; + + else + rx_data_out <= (others => '0'); + rx_data_valid_out <= '0'; + rx_re_out <= rx_re_r; + + end if; + end process mux; + + comm_req_out <= comm_req_r; + + + main : process (clk, rst_n) + + variable rx_len_v : integer range 0 to 2**tx_len_w_c-1; + + begin -- process main + if rst_n = '0' then -- asynchronous reset (active low) + + state_r <= wait_rx; + comm_req_r <= '0'; + rx_status_r <= (others => '0'); + rx_len_r <= 0; + clear_interrupt_r <= '0'; + + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + config_valid_out <= '0'; + read_not_write_out <= '0'; + rx_re_r <= '0'; + rx_len_out <= (others => '0'); + new_rx_out <= '0'; + rx_erroneous_out <= '0'; + fatal_error_out <= '0'; + frame_type_out <= (others => '0'); + header_cnt_r <= 0; + + + elsif clk'event and clk = '1' then -- rising clock edge + + case state_r is + + when wait_rx => + + rx_erroneous_out <= '0'; + + -- notification from int handler + if rx_waiting_in = '1' then + -- ask for a turn + comm_req_r <= '1'; + end if; + + if comm_req_r = '1' and comm_grant_in = '1' then + -- our turn + state_r <= peek_first_byte; + end if; + + + when peek_first_byte => + + -- this is just a dummy read, returned value is rubbish for some + -- reason... + reg_addr_out <= rx_peek_reg_c; + read_not_write_out <= '1'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + config_valid_out <= '0'; + if data_from_comm_valid_in = '1' then + state_r <= delay; + end if; + end if; + + + when delay => + + -- the chip needs a bit time after reading from rx_peek_reg_c + if delay_done_r = '1' then + delay_done_r <= '0'; + if clear_interrupt_r = '1' then + state_r <= clear_interrupt; + else + state_r <= prepare_comm; + end if; + else + delay_done_r <= '1'; + end if; + + + when clear_interrupt => + + -- Clearing interrupt flag. This is done only if we have already + -- received one transmission, and find out that there is another when + -- in check_next state. + reg_addr_out <= ISR_c; + read_not_write_out <= '0'; + config_valid_out <= '1'; + -- rx received interrupt flag (index 0) is cleared by writing 1 to it + config_data_out <= (0 => '1', others => '0'); + + if comm_busy_in = '1' then + config_valid_out <= '0'; + clear_interrupt_r <= '0'; + end if; + + if comm_busy_in = '0' and clear_interrupt_r = '0' then + state_r <= prepare_comm; + end if; + + + when prepare_comm => + + -- set rx_data_reg + reg_addr_out <= rx_data_reg_c; + read_not_write_out <= '1'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + state_r <= check_first_byte; + end if; + + + when check_first_byte => + + -- the first byte must be either x"01" (rx really waiting) or + -- x"00" (no rx waiting). Any other value means that something + -- has gone terribly wrong. This state should only be entered when + -- there is something to read (after rx interrupt or when there is + -- two or more rx:s waiting), so also the x"00" value is invalid. + + if rx_data_valid_in = '1' then + rx_re_r <= '1'; + end if; + + if rx_data_valid_in = '1' and rx_re_r = '1' then + rx_re_r <= '0'; + + -- status is the upper byte + rx_status_r <= rx_data_in( data_width_c-1 downto 8 ); + + -- the first byte: + if rx_data_in( 7 downto 0 ) = x"01" then + -- everything's ok + state_r <= check_status; + else + -- nothing's ok + state_r <= fatal_error; + end if; + end if; + + + when check_status => + + -- if there's non-zero bits, (excluding the multicast frame bit) + -- something has gone wrong. + if (rx_status_r and "10111111") /= x"00" then + rx_erroneous_out <= '1'; + end if; + + state_r <= get_length; + + + when get_length => + + if rx_data_valid_in = '1' then + rx_re_r <= '1'; + end if; + + if rx_data_valid_in = '1' and rx_re_r = '1' then + rx_re_r <= '0'; + + -- rx length doesn't include the header nor the checksum + rx_len_v := to_integer( unsigned( rx_data_in )) - eth_header_len_c - eth_checksum_len_c; + rx_len_r <= rx_len_v; + rx_len_out <= std_logic_vector( to_unsigned( rx_len_v, tx_len_w_c )); + state_r <= strip_header; + end if; + + + when strip_header => + -- the data contains MAC addresses and frame type, so we must + -- get those before relaying the data. + + if rx_data_valid_in = '1' then + rx_re_r <= '1'; + end if; + + if rx_data_valid_in = '1' and rx_re_r = '1' then + rx_re_r <= '0'; + + if header_cnt_r = 6 then + -- write out the frame type + frame_type_out( 15 downto 8 ) <= rx_data_in( 7 downto 0 ); + frame_type_out( 7 downto 0 ) <= rx_data_in( 15 downto 8 ); + new_rx_out <= '1'; + state_r <= relay_data; + header_cnt_r <= 0; + else + -- do nothing with the MAC addresses + header_cnt_r <= header_cnt_r + 1; + end if; + + end if; + + + + when relay_data => + + if rx_re_in = '1' and rx_data_valid_in = '1' then + new_rx_out <= '0'; + + -- upper level reads two bytes + if rx_len_r <= 2 then + -- those are the last two + rx_len_r <= 0; + state_r <= strip_checksum1; + else + rx_len_r <= rx_len_r - 2; + end if; + end if; + + + when strip_checksum1 => + + if rx_data_valid_in = '1' then + rx_re_r <= '1'; + end if; + + if rx_data_valid_in = '1' and rx_re_r = '1' then + rx_re_r <= '0'; + state_r <= strip_checksum2; + end if; + + + when strip_checksum2 => + + if rx_data_valid_in = '1' then + -- config_valid_out must drop early enough to prevent unwanted reading + config_valid_out <= '0'; + rx_re_r <= '1'; + end if; + + if rx_data_valid_in = '1' and rx_re_r = '1' then + rx_re_r <= '0'; + state_r <= check_next; + end if; + + + when check_next => + + + -- make sure that there's no other rx:s waiting + reg_addr_out <= rx_peek_reg_c; + read_not_write_out <= '1'; + config_valid_out <= '1'; + + if comm_busy_in = '1' then + config_valid_out <= '0'; + + if data_from_comm_valid_in = '1' then + + if data_from_comm_in( 7 downto 0 ) = x"01" then + -- there really is a new rx coming, so we must clear the + -- interrupt (so that we don't get an invalid rx_waiting signal + -- afterwards) + state_r <= delay; + clear_interrupt_r <= '1'; + elsif data_from_comm_in( 7 downto 0 ) = x"00" then + -- nothing incoming + state_r <= wait_rx; + comm_req_r <= '0'; + else + state_r <= fatal_error; + end if; + end if; + end if; + + + when fatal_error => + fatal_error_out <= '1'; + when others => null; + end case; + + end if; + end process main; + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_controller.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_controller.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_controller.vhd (revision 34) @@ -0,0 +1,221 @@ +------------------------------------------------------------------------------- +-- Title : DM9kA controller +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_controller.vhd +-- Author : Jussi Nieminen +-- Company : +-- Last update: 2010-06-30 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Top level +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/24 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use work.DM9kA_ctrl_pkg.all; + +entity DM9kA_controller is + generic ( + disable_rx_g : integer := 0 + ); + + port ( + clk : in std_logic; + rst_n : in std_logic; + eth_clk_out : out std_logic; + eth_reset_out : out std_logic; + eth_cmd_out : out std_logic; + eth_write_out : out std_logic; + eth_read_out : out std_logic; + eth_interrupt_in : in std_logic; + eth_data_inout : inout std_logic_vector( data_width_c-1 downto 0 ); + eth_chip_sel_out : out std_logic; + tx_data_in : in std_logic_vector( data_width_c-1 downto 0 ); + tx_data_valid_in : in std_logic; + tx_re_out : out std_logic; + rx_re_in : in std_logic; + rx_data_out : out std_logic_vector( data_width_c-1 downto 0 ); + rx_data_valid_out : out std_logic; + target_MAC_in : in std_logic_vector( 47 downto 0 ); + new_tx_in : in std_logic; + tx_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 ); + tx_frame_type_in : in std_logic_vector( 15 downto 0 ); + new_rx_out : out std_logic; + rx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 ); + rx_frame_type_out : out std_logic_vector( 15 downto 0 ); + rx_erroneous_out : out std_logic; + ready_out : out std_logic; + fatal_error_out : out std_logic + ); + +end DM9kA_controller; + + +architecture structural of DM9kA_controller is + + signal register_addrs : std_logic_vector( (submodules_c+1) * 8 - 1 downto 0 ); + signal config_datas : std_logic_vector( (submodules_c+1) * 8 - 1 downto 0 ); + signal read_not_writes : std_logic_vector( submodules_c downto 0 ); + signal configs_valid : std_logic_vector( submodules_c downto 0 ); + signal data_to_submodules : std_logic_vector( data_width_c-1 downto 0 ); + signal data_to_sb_valid : std_logic; + signal busy_to_submodules : std_logic; + + signal comm_reqs : std_logic_vector( submodules_c-1 downto 0 ); + signal comm_grants : std_logic_vector( submodules_c-1 downto 0 ); + + signal init_ready : std_logic; + signal init_sleep_time : std_logic_vector( sleep_time_w_c-1 downto 0 ); + signal interrupt : std_logic; + + signal tx_data_send_comm : std_logic_vector( data_width_c-1 downto 0 ); + signal tx_data_valid_send_comm : std_logic; + signal tx_re_comm_send : std_logic; + + signal rx_data_comm_read : std_logic_vector( data_width_c-1 downto 0 ); + signal rx_data_valid_comm_read : std_logic; + signal rx_re_read_comm : std_logic; + signal tx_ready_int_send : std_logic; + signal rx_waiting_int_read : std_logic; + + +------------------------------------------------------------------------------- +begin -- structural +------------------------------------------------------------------------------- + +-- debug_out(15 downto 13) <= comm_reqs; +-- debug_out(12 downto 10) <= comm_grants; + + comm_module: entity work.DM9kA_comm_module + port map ( + clk => clk, + rst_n => rst_n, + comm_requests_in => comm_reqs, + comm_grants_out => comm_grants, + interrupt_out => interrupt, + tx_data_in => tx_data_send_comm, + tx_data_valid_in => tx_data_valid_send_comm, + tx_re_out => tx_re_comm_send, + rx_data_out => rx_data_comm_read, + rx_data_valid_out => rx_data_valid_comm_read, + rx_re_in => rx_re_read_comm, + init_ready_in => init_ready, + init_sleep_time_in => init_sleep_time, + register_addrs_in => register_addrs, + config_datas_in => config_datas, + read_not_write_in => read_not_writes, + configs_valid_in => configs_valid, + data_to_submodules_out => data_to_submodules, + data_to_sb_valid_out => data_to_sb_valid, + busy_to_submodules_out => busy_to_submodules, + eth_data_inout => eth_data_inout, + eth_clk_out => eth_clk_out, + eth_cmd_out => eth_cmd_out, + eth_chip_sel_out => eth_chip_sel_out, + eth_interrupt_in => eth_interrupt_in, + eth_read_out => eth_read_out, + eth_write_out => eth_write_out, + eth_reset_out => eth_reset_out + ); + + init_module: entity work.DM9kA_init_module + port map ( + clk => clk, + rst_n => rst_n, + ready_out => init_ready, + sleep_time_out => init_sleep_time, + reg_addr_out => register_addrs( (submodules_c+1)*8 - 1 downto submodules_c*8 ), + config_data_out => config_datas( (submodules_c+1)*8 - 1 downto submodules_c*8 ), + read_not_write_out => read_not_writes( submodules_c ), + config_valid_out => configs_valid( submodules_c ), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules + ); + + ready_out <= init_ready; + + + send_module: entity work.DM9kA_send_module + port map ( + clk => clk, + rst_n => rst_n, + tx_completed_in => tx_ready_int_send, + comm_req_out => comm_reqs(2), + comm_grant_in => comm_grants(2), + reg_addr_out => register_addrs( 3*8-1 downto 2*8 ), + config_data_out => config_datas( 3*8-1 downto 2*8 ), + read_not_write_out => read_not_writes(2), + config_valid_out => configs_valid(2), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + tx_data_out => tx_data_send_comm, + tx_data_valid_out => tx_data_valid_send_comm, + tx_re_in => tx_re_comm_send, + tx_data_in => tx_data_in, + tx_data_valid_in => tx_data_valid_in, + tx_re_out => tx_re_out, + tx_MAC_addr_in => target_MAC_in, + new_tx_in => new_tx_in, + tx_len_in => tx_len_in, + tx_frame_type_in => tx_frame_type_in + ); + + int_handler_module: entity work.DM9kA_interrupt_handler + port map ( + clk => clk, + rst_n => rst_n, + interrupt_in => eth_interrupt_in, + comm_req_out => comm_reqs(0), + comm_grant_in => comm_grants(0), + rx_waiting_out => rx_waiting_int_read, + tx_ready_out => tx_ready_int_send, + reg_addr_out => register_addrs( 7 downto 0 ), + config_data_out => config_datas( 7 downto 0 ), + read_not_write_out => read_not_writes(0), + config_valid_out => configs_valid(0), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules + ); + + enable_rx: if disable_rx_g = 0 generate + read_module: entity work.DM9kA_read_module + port map ( + clk => clk, + rst_n => rst_n, + rx_waiting_in => rx_waiting_int_read, + rx_data_in => rx_data_comm_read, + rx_data_valid_in => rx_data_valid_comm_read, + rx_re_out => rx_re_read_comm, + reg_addr_out => register_addrs( 2*8-1 downto 8 ), + config_data_out => config_datas( 2*8-1 downto 8 ), + read_not_write_out => read_not_writes(1), + config_valid_out => configs_valid(1), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + comm_req_out => comm_reqs(1), + comm_grant_in => comm_grants(1), + rx_data_out => rx_data_out, + rx_data_valid_out => rx_data_valid_out, + rx_re_in => rx_re_in, + new_rx_out => new_rx_out, + rx_len_out => rx_len_out, + frame_type_out => rx_frame_type_out, + rx_erroneous_out => rx_erroneous_out, + fatal_error_out => fatal_error_out + ); + end generate enable_rx; + + disable_rx: if disable_rx_g = 1 generate + comm_reqs(1) <= '0'; + end generate disable_rx; + +end structural; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_ctrl_pkg.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_ctrl_pkg.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_ctrl_pkg.vhd (revision 34) @@ -0,0 +1,59 @@ +-- package for constants + +library ieee; +use ieee.std_logic_1164.all; + +package DM9kA_ctrl_pkg is + + constant data_width_c : integer := 16; + constant tx_len_w_c : integer := 11; + constant sleep_time_w_c : integer := 32; + constant submodules_c : integer := 3; + + -- init reg addresses + constant NCR_c : std_logic_vector( 7 downto 0 ) := x"00"; + constant NSR_c : std_logic_vector( 7 downto 0 ) := x"01"; + constant TCR_c : std_logic_vector( 7 downto 0 ) := x"02"; + constant RCR_c : std_logic_vector( 7 downto 0 ) := x"05"; + constant BPTR_c : std_logic_vector( 7 downto 0 ) := x"08"; + constant FCTR_c : std_logic_vector( 7 downto 0 ) := x"09"; + constant FCR_c : std_logic_vector( 7 downto 0 ) := x"0A"; + constant WUCR_r : std_logic_vector( 7 downto 0 ) := x"0F"; + constant GPCR_c : std_logic_vector( 7 downto 0 ) := x"1E"; + constant GPR_c : std_logic_vector( 7 downto 0 ) := x"1F"; + constant TCR2_c : std_logic_vector( 7 downto 0 ) := x"2D"; + constant ETXCSR_c : std_logic_vector( 7 downto 0 ) := x"30"; + constant ISR_c : std_logic_vector( 7 downto 0 ) := x"FE"; + constant IMR_c : std_logic_vector( 7 downto 0 ) := x"FF"; + constant tx_data_reg_c : std_logic_vector( 7 downto 0 ) := x"F8"; + constant rx_data_reg_c : std_logic_vector( 7 downto 0 ) := x"F2"; + constant rx_peek_reg_c : std_logic_vector( 7 downto 0 ) := x"F0"; + -- tx packet length low register address + constant TXPLL_c : std_logic_vector( 7 downto 0 ) := x"FC"; + constant TXPLH_c : std_logic_vector( 7 downto 0 ) := x"FD"; + + -- MAC address registers + constant MAC1_c : std_logic_vector( 7 downto 0 ) := x"10"; + constant MAC2_c : std_logic_vector( 7 downto 0 ) := x"11"; + constant MAC3_c : std_logic_vector( 7 downto 0 ) := x"12"; + constant MAC4_c : std_logic_vector( 7 downto 0 ) := x"13"; + constant MAC5_c : std_logic_vector( 7 downto 0 ) := x"14"; + constant MAC6_c : std_logic_vector( 7 downto 0 ) := x"15"; + + -- MAC address of the device + constant MAC_addr_c : std_logic_vector( 47 downto 0 ) := x"ACDCABBACD00"; + + constant MAC_len_c : integer := 6; + constant eth_header_len_c : integer := 14; + constant eth_checksum_len_c : integer := 4; + + -- sleeping times + constant power_up_sleep_c : integer := 75000; -- 3 ms with 25MHz + constant reset_sleep_c : integer := 125; -- 5 us with 25MHz + + -- whether to raise the tx request bit or not: + -- 0: DM9000A must be configured to start tx in advance (reg ETXCSR) + -- 1: send module raises tx req bit in TCR after writing tx data + constant send_cmd_en_c : integer := 1; + +end DM9kA_ctrl_pkg; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_init_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_init_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_init_module.vhd (revision 34) @@ -0,0 +1,245 @@ +------------------------------------------------------------------------------- +-- Title : Initialization module +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_init_module.vhd +-- Author : Jussi Nieminen +-- Company : +-- Last update: 2010/02/17 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Initializes DM9kA +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/24 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- constants +use work.DM9kA_ctrl_pkg.all; + + +entity DM9kA_init_module is + + port ( + clk : in std_logic; + rst_n : in std_logic; + ready_out : out std_logic; + sleep_time_out : out std_logic_vector( sleep_time_w_c-1 downto 0 ); + reg_addr_out : out std_logic_vector( 7 downto 0 ); + config_data_out : out std_logic_vector( 7 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic + ); + +end DM9kA_init_module; + + +architecture rtl of DM9kA_init_module is + + type init_table_type is record + addr : std_logic_vector( 7 downto 0 ); + value : std_logic_vector( 7 downto 0 ); + writing : std_logic; + sleep_time : integer; + end record; + + constant init_values_c : integer := 24; + type init_table_array is array (0 to init_values_c-1) of init_table_type; + + constant init_table_c : init_table_array := ( + (GPCR_c, x"01", '1', 0), -- 1 + (GPR_c, x"00", '1', power_up_sleep_c), -- power up PHY + (NCR_c, x"03", '1', 500), -- software reset + (NCR_c, x"00", '1', 0), + (GPR_c, x"01", '1', 0), -- shut down PHY, and start it once again + (GPR_c, x"00", '1', 2*power_up_sleep_c), -- don't know why, but it must be done + (ISR_c, x"3F", '1', 0), -- 16bit mode + reseting status + (NSR_c, x"2C", '1', 0), -- 10 reset NSR + (NCR_c, x"00", '1', 0), + + (MAC1_c, MAC_addr_c(47 downto 40), '1', 0), -- MAC address + (MAC2_c, MAC_addr_c(39 downto 32), '1', 0), + (MAC3_c, MAC_addr_c(31 downto 24), '1', 0), + (MAC4_c, MAC_addr_c(23 downto 16), '1', 0), + (MAC5_c, MAC_addr_c(15 downto 8), '1', 0), + (MAC6_c, MAC_addr_c( 7 downto 0), '1', 0), + + (BPTR_c, x"3F", '1', 0), -- send 600 us jam pattern when 3k left in RxRAM + (FCTR_c, x"5A", '1', 0), -- High/low water overflow thresholds + (FCR_c, x"29", '1', 0), -- 20 flow cntrl + (WUCR_r, x"00", '1', 0), -- wake up control (all wake up stuff disabled) + (TCR2_c, x"80", '1', 0), -- led mode 1 + (ETXCSR_c, x"83", '1', 0), -- early transmit OFF. + (IMR_c, x"83", '1', 0), -- interrupt masks, allow rx and tx interrupts + (RCR_c, x"39", '1', 0), -- discard error/too long packets, enable rx + (NSR_c, x"00", '0', 0)); -- 26 test read, bit 6 is link status + + signal init_cnt_r : integer range 0 to init_values_c - 1; + signal ready_r : std_logic; + signal data_from_comm_r : std_logic_vector( data_width_c-1 downto 0 ); + + type init_state_type is (start, read_data, wait_busy, wait_link_up); + signal state_r : init_state_type; + + signal reset_sleep_cnt_r : integer range 0 to reset_sleep_c; + + -- 1 second with 25MHz (yes, it's really necessary) + constant link_wait_time_c : integer := 25000000; + + type wait_link_type is (send_query, wait_reply, idle); + signal wait_link_state_r : wait_link_type; + signal wait_link_cnt_r : integer range 0 to link_wait_time_c; + + + -- how many seconds we wait until we are ready + -- ************************************************************************** + -- * Okay, this might seem a bit weird thing to do (wait n seconds even after + -- * the DM9kA tells us that it's link is up), but there's a reason to it. + -- * When testing this block I noticed, that the PC on the other end needed + -- * some time too to figure out that there is someone who might want to send + -- * something. So if we start sending right after the DM9kA is ready, the PC + -- * might not be ready to receive it. + -- ************************************************************************** + constant continue_times_c : integer := 5; + signal continue_r : integer range 0 to continue_times_c; + + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + ready_out <= ready_r; + + init: process (clk, rst_n) + begin -- process init + if rst_n = '0' then -- asynchronous reset (active low) + + ready_r <= '0'; + init_cnt_r <= 0; + data_from_comm_r <= (others => '0'); + reset_sleep_cnt_r <= 0; + wait_link_cnt_r <= 0; + continue_r <= 0; + sleep_time_out <= (others => '0'); + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + state_r <= start; + wait_link_state_r <= send_query; + + elsif clk'event and clk = '1' then -- rising clock edge + + if reset_sleep_cnt_r /= reset_sleep_c then + -- sleep for a while after reset release + reset_sleep_cnt_r <= reset_sleep_cnt_r + 1; + + elsif ready_r = '0' then + + case state_r is + when start => + + reg_addr_out <= init_table_c( init_cnt_r ).addr; + config_data_out <= init_table_c( init_cnt_r ).value; + read_not_write_out <= not init_table_c( init_cnt_r ).writing; + sleep_time_out <= std_logic_vector( to_unsigned( init_table_c( init_cnt_r ).sleep_time, sleep_time_w_c )); + config_valid_out <= '1'; + + -- change state once busy is up (comm is working) + if comm_busy_in = '1' then + if init_table_c( init_cnt_r ).writing = '0' then + state_r <= read_data; + else + state_r <= wait_busy; + end if; + end if; + + when read_data => + + -- reading is quite useless at the moment, but for example some + -- registers can be cleared by reading if necessary + if data_from_comm_valid_in = '1' then + data_from_comm_r <= data_from_comm_in; + state_r <= wait_busy; + end if; + + when wait_busy => + + if comm_busy_in = '0' then + config_valid_out <= '0'; + + if init_cnt_r = init_values_c-1 then + state_r <= wait_link_up; + else + init_cnt_r <= init_cnt_r + 1; + state_r <= start; + end if; + end if; + + + when wait_link_up => + + -- wait until link is up, before raising ready signal + case wait_link_state_r is + when send_query => + + reg_addr_out <= NSR_c; + config_data_out <= (others => '0'); + read_not_write_out <= '1'; + config_valid_out <= '1'; + wait_link_state_r <= wait_reply; + + when wait_reply => + + if data_from_comm_valid_in = '1' then + if data_from_comm_in(6) = '1' then + -- if bit 6 from NSR - the link up bit - is up, wait continue_times_c + -- more and then continue + continue_r <= continue_r + 1; + end if; + wait_link_state_r <= idle; + config_valid_out <= '0'; + end if; + + when idle => + + if wait_link_cnt_r = link_wait_time_c then + + wait_link_cnt_r <= 0; + -- check if link is up, and raise ready if so + if continue_r = continue_times_c then + ready_r <= '1'; + state_r <= start; + end if; + wait_link_state_r <= send_query; + + else + wait_link_cnt_r <= wait_link_cnt_r + 1; + end if; + when others => null; + end case; + when others => null; + end case; + + else + -- ready_r = '1' + + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + + end if; + end if; + end process init; + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_interrupt_handler.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_interrupt_handler.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/vhd/DM9kA_interrupt_handler.vhd (revision 34) @@ -0,0 +1,155 @@ +------------------------------------------------------------------------------- +-- Title : DM9000A controller, interrupt handler module +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_interrupt_handler.vhd +-- Author : Jussi Nieminen +-- Company : +-- Last update: 2009/09/09 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Activates with interrupt signal and finds out the source of it. +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/26 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use work.DM9kA_ctrl_pkg.all; + + +entity DM9kA_interrupt_handler is + + port ( + clk : in std_logic; + rst_n : in std_logic; + interrupt_in : in std_logic; + comm_req_out : out std_logic; + comm_grant_in : in std_logic; + rx_waiting_out : out std_logic; + tx_ready_out : out std_logic; + reg_addr_out : out std_logic_vector( 7 downto 0 ); + config_data_out : out std_logic_vector( 7 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic + ); + +end DM9kA_interrupt_handler; + + + +architecture rtl of DM9kA_interrupt_handler is + + type check_state_type is (idle, get_status, check_status, clear_isr); + signal check_state_r : check_state_type; + + signal comm_req_r : std_logic; + signal isr_status_r : std_logic_vector( 7 downto 0 ); + signal comm_working_r : std_logic; + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + comm_req_out <= comm_req_r; + + check_int : process (clk, rst_n) + begin -- process check_int + if rst_n = '0' then -- asynchronous reset (active low) + + comm_req_r <= '0'; + rx_waiting_out <= '0'; + tx_ready_out <= '0'; + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + check_state_r <= idle; + isr_status_r <= (others => '0'); + comm_working_r <= '0'; + + elsif clk'event and clk = '1' then -- rising clock edge + + -- these are allowed to be up only one cycle + tx_ready_out <= '0'; + rx_waiting_out <= '0'; + + case check_state_r is + when idle => + + if interrupt_in = '1' then + -- "We have an interrupt! What are you waiting for, magget??! Do + -- something, move like you got a pair!" + + -- "Sir yes sir!" + comm_req_r <= '1'; + + if comm_grant_in = '1' and comm_req_r = '1' then + -- our turn to act + check_state_r <= get_status; + end if; + else + comm_req_r <= '0'; + end if; + + + when get_status => + + reg_addr_out <= ISR_c; + read_not_write_out <= '1'; + config_valid_out <= '1'; + + if data_from_comm_valid_in = '1' then + isr_status_r <= data_from_comm_in( 7 downto 0 ); + check_state_r <= check_status; + config_valid_out <= '0'; + end if; + + + when check_status => + + if isr_status_r(0) = '1' then + -- packet received bit + rx_waiting_out <= '1'; + end if; + + if isr_status_r(1) = '1' then + -- packet transmitted bit + tx_ready_out <= '1'; + end if; + + -- clear the ISR + reg_addr_out <= ISR_c; + read_not_write_out <= '0'; + -- the interrupt status bits are cleared by writing 1 + config_data_out <= x"3F"; + config_valid_out <= '1'; + check_state_r <= clear_isr; + comm_working_r <= '0'; + + when clear_isr => + + if comm_busy_in = '1' then + -- comm is clearing the ISR + comm_working_r <= '1'; + elsif comm_working_r = '1' then + -- comm_busy_in is down and comm has been working -> back to idle + check_state_r <= idle; + comm_req_r <= '0'; + config_valid_out <= '0'; + end if; + + when others => null; + end case; + + end if; + end process check_int; + + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/doc/DM9kA_controller_doc.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/doc/DM9kA_controller_doc.pdf =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/doc/DM9kA_controller_doc.pdf (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/doc/DM9kA_controller_doc.pdf (revision 34)
funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/doc/DM9kA_controller_doc.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/ip-xact/readme.txt =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/ip-xact/readme.txt (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_dm9000a_ctrl/1.0/ip-xact/readme.txt (revision 34) @@ -0,0 +1,2 @@ +IP-XACTs available for UDP/IP + DM9000A CTRL combination, located +in UDP/IP directory. Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_ctrl_pkg.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_ctrl_pkg.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_ctrl_pkg.vhd (revision 34) @@ -0,0 +1,57 @@ +-- package for constants + +library ieee; +use ieee.std_logic_1164.all; + +package lan91c111_ctrl_pkg is + + constant lan91_data_width_c : integer := 32; + + -- Note: LAN91C111 has 15 bits wide address bus, which they index from 1 to 15. + -- Altera (for S180 dev board) erroneously lists total of 20 bits ranging + -- from 0 to 19, but the traces on the PCB for bits 0 and 16...19 go + -- nowhere! + constant lan91_addr_width_c : integer := 15; + + -- LAN91C111 very cleverly uses only 3 bits of its 15 bit wide + -- address bus. Apparently, about two or three more bits are used for + -- indexing multiple LAN91C111 devices on the same bus, but you couldn't + -- easily do that anyway because they all default to the same base address. + -- (You could configure that with an EEPROM.) + + constant real_addr_width_c : integer := 3; + constant base_addr_c : std_logic_vector(lan91_addr_width_c-real_addr_width_c-1 downto 0) := "000000110000"; + + -- To clarify this (this was a bit difficult to first find in the datasheet, so I had to + -- reverse-engineer): + -- A15 A14 A13 A12 A11 A10 A09 A08 A07 A06 A05 A04 A03 A02 A01 + -- 0 0 0 0 0 0 1 1 0 0 0 0 |REAL ADDR| + -- | I call this part base_addr_c | + + constant tx_len_w_c : integer := 11; + constant sleep_time_w_c : integer := 32; + constant submodules_c : integer := 3; + + -- MAC address of the device + constant MAC_addr_c : std_logic_vector( 47 downto 0 ) := x"ACDCABBACD00"; +-- constant MAC_addr_c : std_logic_vector( 47 downto 0 ) := x"000000000000"; + + constant MAC_len_c : integer := 6; + constant eth_header_len_c : integer := 20; -- STATUS WORD, BYTE COUNT, dst MAC, + -- src MAC, type, CONTROL + -- BYTE/LAST DATA BYTE, total 20 + -- bytes or 10 words. + constant eth_checksum_len_c : integer := 4; + + -- sleeping times + constant clk_hz_c : integer := 25000000; -- used only to calculate sleeping + -- times. + + constant max_sleep_c : integer := clk_hz_c*3+1; + + -- sleeping times + constant power_up_sleep_c : integer := 75000; -- 3 ms with 25MHz + constant reset_sleep_c : integer := 125; -- 5 us with 25MHz + + +end lan91c111_ctrl_pkg; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_init_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_init_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_init_module.vhd (revision 34) @@ -0,0 +1,465 @@ +------------------------------------------------------------------------------- +-- Title : Initialization Module for LAN91C111 +-- Project : +------------------------------------------------------------------------------- +-- File : Originally: DM9kA_init_module.vhd +-- Author : Antti Alhonen (Original (simple) DM9000A version by Jussi Nieminen) +-- Company : DCS/TUT +-- Last update: 2011-11-08 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Initializes LAN91C111. Half of the registers on the very same +-- integrated chip are separated from the others for some mystical reason* and are +-- accessed by EMULATING A SERIAL INTERFACE by issuing the serial data signals, +-- including clock timing, through the registers of the other half. YES, you +-- read it correctly, it really is true. +-- Furthermore, some of the configuration options are located in both sections +-- and you have to manually make sure they match in the correct way; or, some of +-- them are fakes and only the ones in the right section really work. In addition, +-- user has to copy information between the sections. Etc. + +-- (*) (yes I know why they did that but that's not an excuse; +-- they probably took two finished designs for MAC & PHY and made a quick +-- hack to connect them together in a way that somehow works but is hell to +-- use; it would be easier to use separate chips. Then, this chip is manufactured +-- for years and years to come. A decent replacement is not made. + +-- The design also seems to suffer from some legacy from the ISA bus era, +-- despite the fact that the chip is NOT (specifically) meant for ISA busses; and +-- AFAIK is introduced years after the ISA went obsolete. Quite the opposite, +-- this is marketed as a chip for direct use with an embedded processor etc. + +-- It probably would have been too easy to: +-- - Put all the configuration registers behind one unified interface (OMG), +-- - ONCE THEY HAVE THE 15-BIT ADDRESS BUS (for some mystical reason), really use *gasp* +-- FIVE bits (instead of the current three), thus eliminating the dumb concept of "IO +-- BANKS" (which, despite the name, has nothing to do with "IO"s). +-- Oh, the DM9000A guys did it like that... The specifications may be in poor English +-- for that chip but it's not completely ****** up. +-- +-- Congratulations for choosing LAN91C111 :-)! Good luck and have fun! +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/24 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- constants +use work.lan91c111_ctrl_pkg.all; + + +entity lan91c111_init_module is + + generic ( + enable_tx_g : std_logic := '1'; + enable_rx_g : std_logic := '1'); + + port ( + clk : in std_logic; + rst_n : in std_logic; + ready_out : out std_logic; + reg_addr_out : out std_logic_vector( real_addr_width_c-1 downto 0 ); + config_data_out : out std_logic_vector( lan91_data_width_c-1 downto 0 ); + nBE_out : out std_logic_vector( 3 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( lan91_data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic + ); + +end lan91c111_init_module; + + +architecture rtl of lan91c111_init_module is + + type init_table_type is record + phy : std_logic; -- If '1', communicate with PHY registers + -- instead of MAC. Addr will be 5 bits + -- instead of 3, value will be 16 bits + -- instead of 32 and nBE will be ignored. + addr : std_logic_vector( 4 downto 0 ); -- for normal MAC operations, use + -- only 2 downto 0. + value : std_logic_vector( lan91_data_width_c-1 downto 0 ); + nBE : std_logic_vector( 3 downto 0 ); + writing : std_logic; + sleep_time : integer range 0 to max_sleep_c; + only_sleep : std_logic; -- don't do anything but sleep. + + poll_until : std_logic; -- use when writing='0'; if set to '1', don't advance to next step until + poll_bit_num : integer; -- poll_bit_num bit of the read value equals to poll_value. Sleeping will + poll_value : std_logic; -- be done on every poll cycle, also after a match. + + copy : std_logic; -- When writing='1', use copy = '1' to write LAST READ VALUE (from + -- the SAME section (phy/mac)) instead of the "value" field; IN ADDITION, + -- if "poll_until" is '1', take the copy_bit_num'th bit FROM THE OTHER SECTION + copy_bit_num: integer; -- and put it in the poll_bit_num'th place. So: copy one bit from the PHY index x to + -- MAC index y; read MAC, READ PHY, write MAC with copy = 1, poll_until = 1, + -- copy_bit_num = x and poll_bit_num = y. (So this is not a poll, just reusing fields. + -- Poll happens only when writing = '0'.) + end record; + + constant init_values_c : integer := 28; + type init_table_array is array (0 to init_values_c-1) of init_table_type; + + -- Remember: manually change the bank to 3 before entering any PHY commands. + constant init_table_c : init_table_array := ( +-- PHY ADDR DATA nBE W? Sleep Sleep_only POLL, POLLBIT, POLLVAL, COPY, COPYBIT + ('0', "00000", x"00000000", "0000", '1', clk_hz_c/20, '1', '0', 0, '0', '0', 0), -- Sleep 50 ms + ('0', "00111", x"00000000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 0 + ('0', "00010", x"00008000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Soft reset + ('0', "00010", x"00000000", "1100", '1', clk_hz_c/20, '0', '0', 0, '0', '0', 0), -- Clear soft reset and sleep 50 ms. + ('0', "00000", x"000000" & "0000000" & enable_tx_g,"1100", '1', 0, '0', '0', 0, '0', '0', 0), -- TX Enable according to enable_tx_g. Padding doesn't work, don't bother + ('0', "00101", x"0000" & "00111000" & "00010000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Autonegotiation on, leds. +-- Reset the PHY to start autonegotiation. + ('0', "00111", x"00000003", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 3 + ('1', "00000", x"00008000", "1100", '1', clk_hz_c/20, '0', '0', 0, '0', '0', 0), -- Reset PHY, sleep 50 ms. + ('1', "00000", x"0000" & "0011000100000000", "1100", '1', clk_hz_c*2, '0', '0', 0, '0', '0', 0), -- PHY isolation mode off, ANEG on. Sleep 2 sec. +-- ('1', "00010", x"00000000", "1100", '0', 50 ,'0', '0', 0, '0', '0', 0), -- DEBUG: Read reg 2 from PHY, company ID. + ('1', "00001", x"00000000", "1100", '0', clk_hz_c/200,'0', '1', 5, '1', '0', 0), -- Poll for ANEG_ACK in PHY for every 5 ms until '1'. + ('1', "00001", x"00000000", "1100", '0', clk_hz_c/200,'0', '1', 2, '1', '0', 0), -- Poll for LINK in PHY for every 5 ms until '1'. +-- Autonegotiation is done. +-- Now, copy one PHY register bit to appropriate location in the MAC register. + ('0', "00111", x"00000000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 0 + ('0', "00000", x"00000000", "1100", '0', 0, '0', '0', 0, '0', '0', 0), -- Read BANK 0 offset 0 to get a local copy here (MAC). + ('0', "00111", x"00000003", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 3 to be able to access PHY. + ('1', "10010", x"00000000", "1100", '0', 0, '0', '0', 0, '0', '0', 0), -- Read PHY register 18 to get a local copy here (PHY). + ('0', "00111", x"00000000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 0 + ('0', "00000", x"ACDCABBA", "1100", '1', 0, '0', '1', 15, '0', '1', 6), -- Copy bit 6 from PHY we read earlier to MAC offset 0 bit 15. + +-- Now, configure all MAC registers: + ('0', "00111", x"00000000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 0 + ('0', "00010", x"0000" & "0000001" & enable_rx_g & x"00", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- STRIP CRC = on, RX enable according to enable_rx_g. + ('0', "00111", x"00000001", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 1 + ('0', "00010", MAC_addr_c(23 downto 16) & MAC_addr_c(31 downto 24) & MAC_addr_c(39 downto 32) & MAC_addr_c(47 downto 40), "0000",'1',0,'0','0',0,'0','0',0), -- MAC Address 32 LSb's. + ('0', "00100", x"0000" & MAC_addr_c(7 downto 0) & MAC_addr_c(15 downto 8),"1100",'1',0,'0','0',0, '0', '0', 0), -- MAC Address 16 MSb's. + ('0', "00110", x"0000" & "0001101000010000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- AUTO_RELEASE on. + ('0', "00111", x"00000002", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Select BANK 2 + ('0', "00000", x"000000" & "01000000", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- Issue MMU Reset Command, just to be sure. + ('0', "00110", x"0000" & "0000000" & enable_rx_g & x"FF", "1100", '1', 0, '0', '0', 0, '0', '0', 0), -- RCV interrupt mask according to enable_rx_g. Also ack all. +-- Alles in Ordnung, and link should be up. Let's sleep for a few seconds so that the other side is up, too. + ('0', "00000", x"ACDCABBA", "1111", '1', clk_hz_c*3, '1', '0', 0, '0', '0', 0), -- Sleep only, three seconds. +-- ('0', "00110", x"00000000", "1100", '0', 50 ,'0', '0', 0, '0', '0', 0), -- DEBUG: Read that interrupt mask register. + ('0', "00000", x"ACDCABBA", "1111", '1', clk_hz_c*3, '1', '0', 0, '0', '0', 0) -- Sleep only, three seconds. + ); -- And note, we left in BANK 2, as we should!! Other modules expect this. + + + signal init_cnt_r : integer range 0 to init_values_c - 1; + signal ready_r : std_logic; + signal data_from_comm_r : std_logic_vector( lan91_data_width_c-1 downto 0 ); + + type init_state_type is (start, read_data, wait_busy, sleep, phy_horror, finished); + signal state_r : init_state_type; + + type phy_horror_state_type is (start_horror, + write1, wait1, write2, wait2, write3, wait3, + read3, waitread -- they come after wait2, only if reading + ); + + signal phy_horror_state_r : phy_horror_state_type; + + constant phy_horror_length_c : integer := 64; -- PHY configuration horror + -- cycle lasts for 64 serial + -- clock cycles, including the + -- "IDLE" period that could be + -- called a START CONDITION + -- as it is a condition for + -- a successful start. + + signal phy_horror_counter_r : integer range 0 to phy_horror_length_c; + -- let's use 250 ns waiting time between clk cycles. There is some extra + -- cycles in addition to this. + constant phy_horror_wait_time_c : integer := clk_hz_c/4000000; + signal phy_horror_wait_cnt_r : integer range 0 to phy_horror_wait_time_c; + -- Phy horror register includes first (leftmost) 34 bits hard-wired to the start condition. + -- Rightmost bits are registers. Leftmosts (MSb's) are send first. Register + -- is set before the sending of the serial bits starts. + signal phy_horror_register_r : std_logic_vector(phy_horror_length_c-1 downto 0); + signal phy_horror_interface_MDOE_r : std_logic; -- '0' if we want to instruct the Phy horror interface to hi-Z state. + signal phy_horror_read_data_flowing_r : std_logic; -- Comes high two Horror Cycles after + -- MDOE_r goes low. + + signal horror_read_r : std_logic_vector(15 downto 0); + + signal reset_sleep_cnt_r : integer range 0 to reset_sleep_c; + signal sleep_cnt_r : integer range 0 to max_sleep_c; + + -- 1 second with 25MHz (yes, it's really necessary) + constant link_wait_time_c : integer := 25000000; + + + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + assert phy_horror_wait_time_c > 0 report "this has to be 1 or more" severity failure; + + ready_out <= ready_r; + + -- Concurrent part of the phy_horror_register: the start condition consisting + -- of things called "IDLE" and "START BITS". + phy_horror_register_r(63 downto 30) <= "1111111111111111111111111111111101"; + + init: process (clk, rst_n) + begin -- process init + if rst_n = '0' then -- asynchronous reset (active low) + + ready_r <= '0'; + init_cnt_r <= 0; + data_from_comm_r <= (others => '0'); + reset_sleep_cnt_r <= 0; + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + state_r <= start; + phy_horror_state_r <= start_horror; + + horror_read_r <= (others => '0'); + sleep_cnt_r <= 0; + + + elsif clk'event and clk = '1' then -- rising clock edge + + -- DEFAULTS: + config_valid_out <= '0'; + + if reset_sleep_cnt_r /= reset_sleep_c then + -- sleep for a while after reset release + reset_sleep_cnt_r <= reset_sleep_cnt_r + 1; + + elsif ready_r = '0' then + + case state_r is + when start => + if init_table_c(init_cnt_r).only_sleep = '1' then + sleep_cnt_r <= init_table_c(init_cnt_r).sleep_time; + state_r <= sleep; + elsif init_table_c(init_cnt_r).phy = '1' then + -- Enter the psycho mode. + state_r <= phy_horror; + else + -- A _*NORMAL*_ OPERATION (at least quite normal)! + reg_addr_out <= init_table_c( init_cnt_r ).addr(real_addr_width_c-1 downto 0); + if init_table_c( init_cnt_r ).copy = '1' then + config_data_out <= data_from_comm_r; + if init_table_c(init_cnt_r).poll_until = '1' then -- this means the "modify" command. + config_data_out(init_table_c(init_cnt_r).poll_bit_num) <= horror_read_r(init_table_c(init_cnt_r).copy_bit_num); + -- bypass this one bit. + end if; + else + config_data_out <= init_table_c( init_cnt_r ).value; + end if; + read_not_write_out <= not init_table_c( init_cnt_r ).writing; + nBE_out <= init_table_c( init_cnt_r ).nBE; + config_valid_out <= '1'; + + -- change state once busy is up (comm is working) + if comm_busy_in = '1' then + if init_table_c( init_cnt_r ).writing = '0' then + state_r <= read_data; + else + state_r <= wait_busy; + end if; + end if; + end if; + + when read_data => + + -- reading is quite useless at the moment, but for example some + -- registers can be cleared by reading if necessary + if data_from_comm_valid_in = '1' then + data_from_comm_r <= data_from_comm_in; + state_r <= wait_busy; + end if; + + when wait_busy => + if comm_busy_in = '0' then + sleep_cnt_r <= init_table_c(init_cnt_r).sleep_time; + state_r <= sleep; + end if; + + when sleep => + if sleep_cnt_r /= 0 then + sleep_cnt_r <= sleep_cnt_r - 1; + else + -- Were we polling something? + if init_table_c(init_cnt_r).poll_until = '1' and + ((init_table_c(init_cnt_r).phy = '1' and horror_read_r(init_table_c(init_cnt_r).poll_bit_num) /= init_table_c(init_cnt_r).poll_value) or + (init_table_c(init_cnt_r).phy = '0' and data_from_comm_r(init_table_c(init_cnt_r).poll_bit_num) /= init_table_c(init_cnt_r).poll_value)) + then + state_r <= start; -- back to start to poll again! + else + -- We were not polling, or got what we wanted. + if init_cnt_r = init_values_c-1 then + state_r <= finished; + else + init_cnt_r <= init_cnt_r + 1; -- to next row. + state_r <= start; + end if; + end if; + end if; + + when phy_horror => + case phy_horror_state_r is + when start_horror => + phy_horror_register_r(29 downto 0) <= + not init_table_c(init_cnt_r).writing & + init_table_c(init_cnt_r).writing & + "00000" & + init_table_c(init_cnt_r).addr(4 downto 0) & + "10" & -- "turnaround" is written always + -- as "10". Request for high-impedance + -- is done separately. + init_table_c(init_cnt_r).value(15 downto 0); + + if init_table_c( init_cnt_r ).copy = '1' then + phy_horror_register_r(15 downto 0) <= horror_read_r; -- bypass the value. + if init_table_c(init_cnt_r).poll_until = '1' then -- this means the "modify" command. + phy_horror_register_r(init_table_c(init_cnt_r).poll_bit_num) <= data_from_comm_r(init_table_c(init_cnt_r).copy_bit_num); + -- bypass this one bit. + end if; + end if; + + phy_horror_counter_r <= phy_horror_length_c-1; + -- Everything will be 16 bit writes to the same stupid + -- "Management Interface" register. + reg_addr_out <= "100"; + nBE_out <= "1100"; + phy_horror_interface_MDOE_r <= '1'; + phy_horror_read_data_flowing_r <= '0'; + phy_horror_state_r <= write1; + + when write1 => + if comm_busy_in = '0' then + read_not_write_out <= '0'; + config_data_out <= x"0000" & "00110011" & "0011" + & phy_horror_interface_MDOE_r + & '0' -- MCLK + & '0' -- MDI + & phy_horror_register_r(phy_horror_counter_r); + config_valid_out <= '1'; + phy_horror_state_r <= wait1; + phy_horror_wait_cnt_r <= phy_horror_wait_time_c; + end if; + + when wait1 => + if comm_busy_in = '0' then + if phy_horror_wait_cnt_r = 0 then + if init_table_c(init_cnt_r).writing = '0' and phy_horror_read_data_flowing_r = '1' then + phy_horror_state_r <= read3; + else + phy_horror_state_r <= write2; + end if; + else + phy_horror_wait_cnt_r <= phy_horror_wait_cnt_r - 1; + end if; + end if; + + when write2 => + if comm_busy_in = '0' then + read_not_write_out <= '0'; + config_data_out <= x"0000" & "00110011" & "0011" + & phy_horror_interface_MDOE_r + & '1' -- OOOOOOOHHH, create the clock edge!!!! + & '0' -- MDI + & phy_horror_register_r(phy_horror_counter_r); + config_valid_out <= '1'; + phy_horror_state_r <= wait2; + phy_horror_wait_cnt_r <= phy_horror_wait_time_c; + end if; + + when wait2 => + if comm_busy_in = '0' then + if phy_horror_wait_cnt_r = 0 then + phy_horror_state_r <= write3; + else + phy_horror_wait_cnt_r <= phy_horror_wait_cnt_r - 1; + end if; + end if; + + when read3 => + -- This state is skipped when writing. + if comm_busy_in = '0' then + read_not_write_out <= '1'; -- read operation to the same addr + config_valid_out <= '1'; + phy_horror_state_r <= waitread; + end if; + + when waitread => + -- This state is skipped when writing. + if data_from_comm_valid_in = '1' then + -- data valid means also not busy so no need to check that. + -- Just read the data we are interested in here + horror_read_r(phy_horror_counter_r) <= data_from_comm_in(1); + phy_horror_state_r <= write2; + end if; + + when write3 => + if comm_busy_in = '0' then + read_not_write_out <= '0'; + config_data_out <= x"0000" & "00110011" & "0011" + & phy_horror_interface_MDOE_r + & '0' -- MCLK Low again, OMG + & '0' -- MDI + & phy_horror_register_r(phy_horror_counter_r); + config_valid_out <= '1'; + phy_horror_state_r <= wait3; + phy_horror_wait_cnt_r <= phy_horror_wait_time_c; + end if; + + when wait3 => + if comm_busy_in = '0' then + if phy_horror_wait_cnt_r = 0 then + if phy_horror_counter_r = 0 then + -- OH YES, we got all the bits done. + phy_horror_state_r <= start_horror; + state_r <= wait_busy; -- This is good, away from the horror FSM. + else + phy_horror_counter_r <= phy_horror_counter_r - 1; + phy_horror_state_r <= write1; -- To the next bit... + if init_table_c(init_cnt_r).writing = '0' then + if phy_horror_counter_r = 18 then + -- Turnaround time. + phy_horror_interface_MDOE_r <= '0'; + elsif phy_horror_counter_r = 16 then + -- Valid data is coming next (hopefully) + phy_horror_read_data_flowing_r <= '1'; + end if; + end if; + end if; + else + phy_horror_wait_cnt_r <= phy_horror_wait_cnt_r - 1; + end if; + end if; + + + when others => null; + end case; + + when finished => + + ready_r <= '1'; + + when others => null; + end case; + + else + -- ready_r = '1' + + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + + end if; + end if; + end process init; + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_interrupt_handler.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_interrupt_handler.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_interrupt_handler.vhd (revision 34) @@ -0,0 +1,152 @@ +------------------------------------------------------------------------------- +-- Title : DM9000A controller, interrupt handler module +-- Project : +------------------------------------------------------------------------------- +-- File : DM9kA_interrupt_handler.vhd +-- Author : Jussi Nieminen +-- Company : +-- Last update: 2011-11-06 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Activates with interrupt signal and finds out the source of it. +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/26 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use work.lan91c111_ctrl_pkg.all; + + +entity lan91c111_interrupt_handler is + + port ( + clk : in std_logic; + rst_n : in std_logic; + interrupt_in : in std_logic; + comm_req_out : out std_logic; + comm_grant_in : in std_logic; + rx_waiting_out : out std_logic; + tx_ready_out : out std_logic; + reg_addr_out : out std_logic_vector( real_addr_width_c-1 downto 0 ); + config_data_out : out std_logic_vector( lan91_data_width_c-1 downto 0 ); + config_nBE_out : out std_logic_vector( 3 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( lan91_data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic + ); + +end lan91c111_interrupt_handler; + + +architecture rtl of lan91c111_interrupt_handler is + + type check_state_type is (idle, get_status, check_status, clear_isr); + signal check_state_r : check_state_type; + + signal comm_req_r : std_logic; + signal isr_status_r : std_logic_vector( 7 downto 0 ); + signal comm_working_r : std_logic; + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + config_nBE_out <= "1100"; + comm_req_out <= comm_req_r; + + check_int : process (clk, rst_n) + begin -- process check_int + if rst_n = '0' then -- asynchronous reset (active low) + + comm_req_r <= '0'; + rx_waiting_out <= '0'; + tx_ready_out <= '0'; + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + read_not_write_out <= '0'; + config_valid_out <= '0'; + check_state_r <= idle; + isr_status_r <= (others => '0'); + comm_working_r <= '0'; + + elsif clk'event and clk = '1' then -- rising clock edge + + -- these are allowed to be up only one cycle + tx_ready_out <= '0'; + rx_waiting_out <= '0'; + + config_valid_out <= '0'; + + case check_state_r is + when idle => + + if interrupt_in = '1' then + -- "We have an interrupt! What are you waiting for, magget??! Do + -- something, move like you got a pair!" + + -- "Sir yes sir!" + comm_req_r <= '1'; + + if comm_grant_in = '1' and comm_req_r = '1' then + -- our turn to act + check_state_r <= get_status; + reg_addr_out <= "110"; + read_not_write_out <= '1'; + config_valid_out <= '1'; + end if; + else + comm_req_r <= '0'; + end if; + + when get_status => + if data_from_comm_valid_in = '1' then + isr_status_r <= data_from_comm_in( 7 downto 0 ); + check_state_r <= check_status; + end if; + + when check_status => + + if isr_status_r(0) = '1' then + -- packet received bit + rx_waiting_out <= '1'; + end if; + + if isr_status_r(1) = '1' then + -- packet transmitted bit + tx_ready_out <= '1'; + end if; + + -- clear the ISR + read_not_write_out <= '0'; + -- the interrupt status bits are cleared by writing 1 + config_data_out <= x"000000FF"; + config_valid_out <= '1'; + check_state_r <= clear_isr; + + comm_working_r <= '0'; + + when clear_isr => + + if comm_busy_in = '1' then + -- comm is clearing the ISR + comm_working_r <= '1'; + elsif comm_working_r = '1' then + -- comm_busy_in is down and comm has been working -> back to idle + check_state_r <= idle; + comm_req_r <= '0'; + end if; + + when others => null; + end case; + + end if; + end process check_int; + + + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/quick_and_dirty_test.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/quick_and_dirty_test.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/quick_and_dirty_test.vhd (revision 34) @@ -0,0 +1,122 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.lan91c111_ctrl_pkg.all; + +entity quick_and_dirty_test is + + port ( + clk : in std_logic; + rst_n : in std_logic; + but_in : in std_logic; + but2_in : in std_logic; + + -- interface to LAN91C111 + eth_data_inout : inout std_logic_vector( lan91_data_width_c-1 downto 0 ); + eth_addr_out : out std_logic_vector( lan91_addr_width_c-1 downto 0 ); + eth_interrupt_in : in std_logic; + eth_read_out : out std_logic; + eth_write_out : out std_logic; + eth_nADS_out : out std_logic; + eth_nAEN_out : out std_logic; + eth_nBE_out : out std_logic_vector(3 downto 0); + + ready_out : out std_logic + + ); + +end quick_and_dirty_test; + +architecture structural of quick_and_dirty_test is + + signal clk25, tx_re : std_logic; + + signal but_r1, but_r, but2_r1, but2_r : std_logic; + + signal but_cnt_r : integer range 0 to 25000000; + + signal tx_len_r : integer range 0 to 1400; + + signal new_tx_r : std_logic; + +begin -- structural + + synch: process (clk, rst_n) + begin -- process synch + if rst_n = '0' then -- asynchronous reset (active low) + but_r1 <= '0'; + but_r <= '0'; + but2_r1 <= '0'; + but2_r <= '0'; + elsif clk'event and clk = '1' then -- rising clock edge + but_r <= but_r1; + but_r1 <= not but_in; + but2_r <= but2_r1; + but2_r1 <= not but2_in; + end if; + end process synch; + + joo: process (clk, rst_n) + begin -- process joo + if rst_n = '0' then -- asynchronous reset (active low) + new_tx_r <= '0'; + tx_len_r <= 28; --899; + elsif clk'event and clk = '1' then -- rising clock edge + if but_cnt_r /= 0 then + but_cnt_r <= but_cnt_r - 1; + end if; + + if but_r = '1' and but_cnt_r = 0 then + new_tx_r <= '1'; + tx_len_r <= tx_len_r + 1; + but_cnt_r <= 25000000; + end if; + + if new_tx_r = '1' and tx_re = '1' then + new_tx_r <= '0'; + end if; + + end if; + end process joo; + + pll_1: entity work.pll + port map ( + inclk0 => clk, + c0 => clk25); + + lan91c111_controller_1: entity work.lan91c111_controller + generic map ( + enable_tx_g => '1', + enable_rx_g => '1', + interface_width_g => 16) + port map ( + clk => clk25, + rst_n => rst_n, + eth_data_inout => eth_data_inout, + eth_addr_out => eth_addr_out, + eth_interrupt_in => eth_interrupt_in, + eth_read_out => eth_read_out, + eth_write_out => eth_write_out, + eth_nADS_out => eth_nADS_out, + eth_nAEN_out => eth_nAEN_out, + eth_nBE_out => eth_nBE_out, + tx_data_in => x"ABCD", + tx_data_valid_in => '1', + tx_re_out => tx_re, + rx_re_in => '1', + rx_data_out => open, + rx_data_valid_out => open, + target_MAC_in => x"000102CEF343", -- vanha kone +-- target_MAC_in => x"FFFFFFFFFFFF", + new_tx_in => new_tx_r or but2_r, + tx_len_in => std_logic_vector(to_unsigned(tx_len_r, 11)), + tx_frame_type_in => x"0800", + new_rx_out => open, + rx_len_out => open, + rx_frame_type_out => open, + rx_erroneous_out => open, + ready_out => ready_out, + fatal_error_out => open); + +end structural; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_comm_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_comm_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_comm_module.vhd (revision 34) @@ -0,0 +1,281 @@ +------------------------------------------------------------------------------- +-- Title : Communication module for the LAN91C111 controller +-- Project : +------------------------------------------------------------------------------- +-- File : Lan91c111_comm_module.vhd +-- Author : Jussi Nieminen, Antti Alhonen +-- Last update: 2011-11-06 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/21 1.0 niemin95 Created +-- 2011/07/17 2.0 alhonena Modified for LAN91C111 +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.lan91c111_ctrl_pkg.all; + +entity lan91c111_comm_module is + port ( + clk : in std_logic; -- 25 MHz + rst_n : in std_logic; + comm_requests_in : in std_logic_vector( submodules_c-1 downto 0 ); + comm_grants_out : out std_logic_vector( submodules_c-1 downto 0 ); + interrupt_out : out std_logic; + init_ready_in : in std_logic; + -- interface to submodules (and to init block) + register_addrs_in : in std_logic_vector( (submodules_c+1) * real_addr_width_c - 1 downto 0 ); -- from each submodule + config_datas_in : in std_logic_vector( (submodules_c+1) * lan91_data_width_c - 1 downto 0 ); + config_nBEs_in : in std_logic_vector( (submodules_c+1) * 4 - 1 downto 0 ); + read_not_write_in : in std_logic_vector( submodules_c downto 0 ); + configs_valid_in : in std_logic_vector( submodules_c downto 0 ); + data_to_submodules_out : out std_logic_vector( lan91_data_width_c - 1 downto 0 ); + data_to_sb_valid_out : out std_logic; + busy_to_submodules_out : out std_logic; + -- interface to LAN91C111 + eth_data_inout : inout std_logic_vector( lan91_data_width_c-1 downto 0 ); + eth_addr_out : out std_logic_vector( lan91_addr_width_c-1 downto 0 ); + eth_interrupt_in : in std_logic; + eth_read_out : out std_logic; + eth_write_out : out std_logic; + eth_nADS_out : out std_logic; + eth_nAEN_out : out std_logic; + eth_nBE_out : out std_logic_vector(3 downto 0) + ); + +end lan91c111_comm_module; + + +architecture rtl of lan91c111_comm_module is + + -- Major change compared to DM9000A controller by Jussi Nieminen; + -- Data muxes between "config_data", "tx data" and "rx data" have + -- been moved completely to the Send and Read modules; this module takes only + -- one type of input from Send and Read, not two types. Hence, this + -- module is simplified a lot. + -- The major reason for the change is that whereas DM9000A does not include + -- "register address" for every write/read operation, LAN91C111 does; all + -- data is accessed via a single register address, pointed by a separate + -- pointer register with its own address. + + -- WRITING AND READING PROCEDURES by comm_state_r + -- wait_valid: + -- Wait until one of the submodules wants to write or read. Immediately put + -- the address (and data in case of write) on the busses and go to write_data + -- or read_data, which asserts write or read enable signal to the chip. + -- + -- write_data: + -- Set write_out low. Go to data_written. + -- + -- read_data: + -- Set read_out low. Go to data_read. + -- + -- data_written: + -- Set write_out high. Go to wait_valid. + -- + -- data_read: + -- Read the data. Set read_out high. Go to wait_valid. + -- + -- Example of the read operation: + -- |1 |2 |3 |4 |5 |6 | + -- config_valid_in ___---------------- + -- readnotwrite ___---------------- + -- addr_out xxxxxx< ADDR >xxxx (valid for 3 cycles) + -- data_out xxxxxxZZZZZZZZZxxxx (valid for 3 cycles) + -- nEth_read_out ---------___------ (1 cycle long in the middle) + -- Read data here: <> (on the rising edge of read enable signal) + -- + -- Example of the write operation: + -- |1 |2 |3 |4 |5 |6 | + -- config_valid_in ___---------------- + -- readnotwrite ___________________ + -- addr_out xxxxxx< ADDR >xxxx (valid for 3 cycles) + -- data_out xxxxxx< DATA >xxxx (valid for 3 cycles) + -- nEth_write_out ---------___------ (1 cycle long in the middle) + + + type comm_state_type is (wait_valid, write_data, data_written, read_data, data_read); + signal comm_state_r : comm_state_type; + + -- Arbiter side selects one of the incoming communication requests and feeds + -- data to these: + signal register_addr : std_logic_vector( real_addr_width_c-1 downto 0 ); + signal config_data : std_logic_vector( lan91_data_width_c-1 downto 0 ); + signal config_nBE : std_logic_vector( 3 downto 0 ); + signal read_not_write : std_logic; -- 1 = read, 0 = write + signal config_valid : std_logic; + + signal comm_grants_r : std_logic_vector( submodules_c-1 downto 0 ); + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + -- concurrent assignments + comm_grants_out <= comm_grants_r; + interrupt_out <= eth_interrupt_in; + eth_nADS_out <= '0'; + eth_nAEN_out <= '0'; + + arbitration: process (clk, rst_n) + variable reserved_v : std_logic; + begin -- process arbitration + if rst_n = '0' then -- asynchronous reset (active low) + + comm_grants_r <= (others => '0'); + + elsif clk'event and clk = '1' then -- rising clock edge + + reserved_v := '0'; + + if init_ready_in = '1' then + -- can't use 'others' in comparison, so we do it this way + if comm_grants_r = std_logic_vector( to_unsigned( 0, submodules_c )) then + + -- no one is using comm_module right now + -- lowest index wins + for n in 0 to submodules_c-1 loop + if comm_requests_in(n) = '1' then + if reserved_v = '0' then + comm_grants_r(n) <= '1'; + reserved_v := '1'; + end if; + end if; + end loop; -- n + + else + + -- clear grant when request goes out + for n in 0 to submodules_c-1 loop + if comm_grants_r(n) = '1' and comm_requests_in(n) = '0' then + comm_grants_r(n) <= '0'; + end if; + end loop; -- n + + end if; + + else + -- no grants during initialization + comm_grants_r <= (others => '0'); + end if; + + end if; + end process arbitration; + + + submodule_mux: process (comm_grants_r, register_addrs_in, config_datas_in, config_nBEs_in, + read_not_write_in, configs_valid_in, init_ready_in) + begin -- process submodule_mux + + if init_ready_in = '0' then + + -- init block has the highest index, but it doesn't compete for it's turn + register_addr <= register_addrs_in( (submodules_c+1)*real_addr_width_c - 1 downto submodules_c*real_addr_width_c ); + config_data <= config_datas_in( (submodules_c+1)*lan91_data_width_c - 1 downto submodules_c*lan91_data_width_c ); + config_nBE <= config_nBEs_in( (submodules_c+1)*4 - 1 downto submodules_c*4 ); + read_not_write <= read_not_write_in( submodules_c ); + config_valid <= configs_valid_in( submodules_c ); + + else + -- init ready, normal arbitration + + -- default: + register_addr <= (others => '0'); + config_data <= (others => '0'); + config_nBE <= (others => '0'); + read_not_write <= '0'; + config_valid <= '0'; + + -- grant signal decides + for n in 0 to submodules_c-1 loop + + if comm_grants_r(n) = '1' then + register_addr <= register_addrs_in( (n+1)*real_addr_width_c - 1 downto n*real_addr_width_c ); + config_data <= config_datas_in( (n+1)*lan91_data_width_c - 1 downto n*lan91_data_width_c ); + config_nBE <= config_nBEs_in( (n+1)*4 - 1 downto n*4 ); + read_not_write <= read_not_write_in(n); + config_valid <= configs_valid_in(n); + end if; + end loop; -- n + end if; + + end process submodule_mux; + + + lan91c111_communication: process (clk, rst_n) + begin -- process lan91c111_communication + if rst_n = '0' then -- asynchronous reset (active low) + + eth_write_out <= '1'; + eth_read_out <= '1'; + eth_data_inout <= (others => 'Z'); + + data_to_submodules_out <= (others => '0'); + data_to_sb_valid_out <= '0'; + busy_to_submodules_out <= '0'; + + elsif clk'event and clk = '1' then -- rising clock edge + + -- defaults: + eth_write_out <= '1'; -- remember, active low + eth_read_out <= '1'; + data_to_sb_valid_out <= '0'; -- this is active high + + case comm_state_r is + when wait_valid => + busy_to_submodules_out <= '0'; + + if config_valid = '1' then + busy_to_submodules_out <= '1'; + eth_addr_out <= base_addr_c & register_addr; + if read_not_write = '1' then + eth_data_inout <= (others => 'Z'); + comm_state_r <= read_data; + else + eth_data_inout <= config_data; + comm_state_r <= write_data; + end if; + + eth_nBE_out <= config_nBE; + + end if; + + when write_data => + eth_write_out <= '0'; + comm_state_r <= data_written; + + when data_written => + busy_to_submodules_out <= '0'; + comm_state_r <= wait_valid; + + when read_data => + eth_read_out <= '0'; + comm_state_r <= data_read; + + when data_read => + busy_to_submodules_out <= '0'; + -- read the data here: + data_to_submodules_out <= eth_data_inout; + data_to_sb_valid_out <= '1'; -- It is important that the + -- busy_to_submodules_out goes low no + -- later than valid goes high. + -- Currently, the other modules rely on + -- that to simplify the state machines. + + -- Also note that data_to_sb_valid_out is high only for one clock cycle + -- and you must read the data immediately. + + -- eth_data_inout is left in high-impedance state. If needed for some + -- reason, you can write something else to it here. + comm_state_r <= wait_valid; + + when others => null; + end case; + end if; + end process lan91c111_communication; + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_read_module.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_read_module.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_read_module.vhd (revision 34) @@ -0,0 +1,334 @@ +------------------------------------------------------------------------------- +-- Title : LAN91C111 controller, read module +-- Project : +------------------------------------------------------------------------------- +-- File : Original: DM9kA_read_module.vhd +-- Author : Jussi Nieminen (Antti Alhonen for LAN91C111) +-- Last update: 2011-11-07 +------------------------------------------------------------------------------- +-- Description: Handles reading of rx data from LAN91C111 +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/09/02 1.0 niemin95 Created +-- 2011/07/?? lan91c111 alhonena +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.lan91c111_ctrl_pkg.all; + + +entity lan91c111_read_module is + + generic ( + mode_16bit_g : integer := 0); + + port ( + clk : in std_logic; + rst_n : in std_logic; + -- from interrupt handler + rx_waiting_in : in std_logic; + -- from/to comm module + reg_addr_out : out std_logic_vector( real_addr_width_c-1 downto 0 ); + config_data_out : out std_logic_vector( lan91_data_width_c-1 downto 0 ); + nBE_out : out std_logic_vector( 3 downto 0 ); + read_not_write_out : out std_logic; + config_valid_out : out std_logic; + data_from_comm_in : in std_logic_vector( lan91_data_width_c-1 downto 0 ); + data_from_comm_valid_in : in std_logic; + comm_busy_in : in std_logic; + comm_req_out : out std_logic; + comm_grant_in : in std_logic; + -- from/to upper level + rx_data_out : out std_logic_vector( lan91_data_width_c-1 downto 0 ); + rx_data_valid_out : out std_logic; + rx_bytes_valid_out : out std_logic_vector( 3 downto 0); -- you may want to use this to help reading, or as a debug signal, or to ignore it. + rx_re_in : in std_logic; + new_rx_out : out std_logic; + rx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 ); -- Actual number of bytes of payload. + frame_type_out : out std_logic_vector( 15 downto 0 ); + rx_erroneous_out : out std_logic; + fatal_error_out : out std_logic -- worse than some network error + ); + +end lan91c111_read_module; + + +architecture rtl of lan91c111_read_module is + + type read_state_type is (wait_rx, -- wait until interrupt module rises rx_waiting_in. + set_pointer_to_status, -- set the pointer register to read packet status. + read_status_and_len, -- read the packet status and length + frame_type, -- Ethernet frame type is read. + frame_type2, + start_read, + read_normal, + read_last_24, + read_last_16, + read_last_odd, + wait_re, + remove_from_fifo, -- issue a command to MMU to remove the RX and free memory. + wait_for_mmu, -- poll the MMU until it has processed the command. + check_mmu, + check_for_more); -- check if there are more rx's in the FIFO. + + signal state_r : read_state_type; + + signal comm_req_r : std_logic; + + signal rx_len_r : integer range 0 to 2**tx_len_w_c-1; + + signal config_valid_r : std_logic; + + signal first_r : std_logic; + + signal new_r : std_logic; + + signal new_rx_r : std_logic; + signal rx_data_valid_r : std_logic; + + constant pnt_set_wait_cnt_c : integer := clk_hz_c/2702702; -- 370 ns wait after pointer is set. + signal pnt_set_wait_cnt_r : integer range 0 to pnt_set_wait_cnt_c; + +------------------------------------------------------------------------------- +begin -- rtl +------------------------------------------------------------------------------- + + comm_req_out <= comm_req_r; + + config_valid_out <= config_valid_r; + + new_rx_out <= new_rx_r; + + rx_data_valid_out <= rx_data_valid_r; + + main : process (clk, rst_n) + + variable rx_len_v : integer range 0 to 2**tx_len_w_c-1; + + begin -- process main + if rst_n = '0' then -- asynchronous reset (active low) + + state_r <= wait_rx; + comm_req_r <= '0'; + rx_len_r <= 0; + + reg_addr_out <= (others => '0'); + config_data_out <= (others => '0'); + config_valid_r <= '0'; + read_not_write_out <= '0'; + rx_len_out <= (others => '0'); + rx_erroneous_out <= '0'; + fatal_error_out <= '0'; + frame_type_out <= (others => '0'); + new_r <= '0'; + + new_rx_r <= '0'; + rx_data_valid_r <= '0'; + + elsif clk'event and clk = '1' then -- rising clock edge + + if new_rx_r = '1' and rx_re_in = '1' then + new_rx_r <= '0'; + end if; + + if rx_data_valid_r = '1' and rx_re_in = '1' then + rx_data_valid_r <= '0'; + end if; + + -- DEFAULTS: + config_valid_r <= '0'; + + + case state_r is + + when wait_rx => + -- notification from int handler + if rx_waiting_in = '1' or new_r = '1' then + new_r <= '0'; + -- ask for a turn + comm_req_r <= '1'; + end if; + + if comm_req_r = '1' and comm_grant_in = '1' and comm_busy_in = '0' then + -- our turn + state_r <= set_pointer_to_status; + -- again, we suppose that we are in BANK 2. + config_data_out <= x"0000" & "11100" & "000" & x"00"; -- pointer to 0 (status), with rcv, read, autoincr. + reg_addr_out <= "011"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1'; + pnt_set_wait_cnt_r <= pnt_set_wait_cnt_c; + end if; + + when set_pointer_to_status => + if comm_busy_in = '0' and config_valid_r = '0' then + if pnt_set_wait_cnt_r = 0 then + -- pointer set, start reading. + reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_status_and_len; + else + pnt_set_wait_cnt_r <= pnt_set_wait_cnt_r - 1; + end if; + end if; + + when read_status_and_len => + if data_from_comm_valid_in = '1' then -- this also means "not busy", remember that? + rx_erroneous_out <= data_from_comm_in(10) or -- too short + data_from_comm_in(11) or -- too long + data_from_comm_in(13) or -- bad crc + data_from_comm_in(15); -- alignment error. + rx_len_v := to_integer(unsigned(data_from_comm_in(16+11-1 downto 17) & data_from_comm_in(12))) - 16; -- actual data length. + rx_len_r <= rx_len_v; + rx_len_out <= std_logic_vector(to_unsigned(rx_len_v, tx_len_w_c)); + + config_data_out <= x"0000" & "11100" & "000" & x"10"; -- set pointer to 16 (frame type), with rcv, read, autoincr. + reg_addr_out <= "011"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1'; + pnt_set_wait_cnt_r <= pnt_set_wait_cnt_c; + state_r <= frame_type; + end if; + + when frame_type => + if comm_busy_in ='0' and config_valid_r = '0' then + if pnt_set_wait_cnt_r = 0 then + reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; -- 16 bit read for frame type. + state_r <= frame_type2; + else + pnt_set_wait_cnt_r <= pnt_set_wait_cnt_r - 1; + end if; + end if; + + when frame_type2 => + if data_from_comm_valid_in = '1' then + frame_type_out <= data_from_comm_in(7 downto 0) & data_from_comm_in(15 downto 8); + new_rx_r <= '1'; + state_r <= start_read; + first_r <= '1'; + end if; + + when start_read => + if rx_re_in = '1' or first_r = '1' then -- previous word was read by the application; or this is the first word. + first_r <= '0'; + + if mode_16bit_g = 1 then + -- 16-bit mode: + if rx_len_r = 1 then + reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_last_odd; -- zero "data area" left; read control byte and last data byte. + else + reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_normal; -- normal 16-bit read. + end if; + + else + -- Original 32-bit mode: + if rx_len_r = 1 then + reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_last_odd; -- zero "data area" left; read control byte and last data byte. + elsif rx_len_r = 2 then + reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_last_16; -- two bytes of "data area" left; read it and ignore ctrl byte and last byte. + elsif rx_len_r = 3 then + reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_last_24; -- two bytes of "data area" left; do a 32-bit read to data + ctrl + odd byte. + else + reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= read_normal; -- normal 32-bit read. + end if; + + end if; + + end if; + + when read_normal => + if data_from_comm_valid_in = '1' then + rx_data_valid_r <= '1'; + rx_data_out <= data_from_comm_in; + if mode_16bit_g = 1 then + rx_bytes_valid_out <= "0011"; + else + rx_bytes_valid_out <= "1111"; + end if; + state_r <= start_read; + if (mode_16bit_g = 0 and rx_len_r = 4) or + (mode_16bit_g = 1 and rx_len_r = 2) then -- this was last and it was even. + state_r <= wait_re; + end if; + if mode_16bit_g = 1 then + rx_len_r <= rx_len_r - 2; + else + rx_len_r <= rx_len_r - 4; + end if; + end if; + + when read_last_24 => + assert mode_16bit_g = 0 report "Shouldn't be here!" severity failure; + + if data_from_comm_valid_in = '1' then + rx_data_valid_r <= '1'; + rx_data_out <= x"00" & data_from_comm_in(23 downto 0); + rx_bytes_valid_out <= "0111"; + state_r <= wait_re; + end if; + + when read_last_16 => + assert mode_16bit_g = 0 report "Shouldn't be here!" severity failure; + + if data_from_comm_valid_in = '1' then + rx_data_valid_r <= '1'; + rx_data_out <= x"0000" & data_from_comm_in(15 downto 0); + rx_bytes_valid_out <= "0011"; + state_r <= wait_re; + end if; + + when read_last_odd => + if data_from_comm_valid_in = '1' then + rx_data_valid_r <= '1'; + rx_data_out <= x"000000" & data_from_comm_in(7 downto 0); + rx_bytes_valid_out <= "0001"; + state_r <= wait_re; + end if; + + when wait_re => -- wait for last re from the application. + if rx_re_in = '1' then + state_r <= remove_from_fifo; + end if; + + when remove_from_fifo => + if comm_busy_in = '0' and config_valid_r = '0' then + config_data_out <= x"000000" & "10000000"; -- REMOVE AND RELEASE TOP OF RX FIFO + reg_addr_out <= "000"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1'; + state_r <= wait_for_mmu; + end if; + + when wait_for_mmu => + if comm_busy_in = '0' and config_valid_r = '0' then + reg_addr_out <= "000"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + state_r <= check_mmu; + end if; + + when check_mmu => + if data_from_comm_valid_in = '1' then + if data_from_comm_in(0) = '1' then -- BUSY, poll again. + state_r <= wait_for_mmu; + else + state_r <= check_for_more; -- Everything finished, let's check if there are new rx's waiting... + reg_addr_out <= "010"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1'; + end if; + end if; + + when check_for_more => + if data_from_comm_valid_in = '1' then + new_r <= not data_from_comm_in(15); -- RX FIFO not empty. + + state_r <= wait_rx; + comm_req_r <= '0'; + end if; + + when others => null; + end case; + + end if; + end process main; + +end rtl; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_controller.vhd =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_controller.vhd (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/vhd/lan91c111_controller.vhd (revision 34) @@ -0,0 +1,300 @@ +------------------------------------------------------------------------------- +-- Title : LAN91C111 controller +-- Project : +------------------------------------------------------------------------------- +-- File : Originally: DM9kA_controller.vhd +-- Author : Antti Alhonen +-- Company : +-- Last update: 2011-11-08 +-- Platform : +------------------------------------------------------------------------------- +-- Description: Top level +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2009/08/24 1.0 niemin95 Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use work.lan91c111_ctrl_pkg.all; + + +entity lan91c111_controller is + generic ( + enable_tx_g : std_logic := '1'; + enable_rx_g : std_logic := '1'; + interface_width_g : integer := 16 -- 16 or 32. + ); + + port ( + clk : in std_logic; + rst_n : in std_logic; + + -- interface to LAN91C111 + eth_data_inout : inout std_logic_vector( lan91_data_width_c-1 downto 0 ); + eth_addr_out : out std_logic_vector( lan91_addr_width_c-1 downto 0 ); + eth_interrupt_in : in std_logic; + eth_read_out : out std_logic; + eth_write_out : out std_logic; + eth_nADS_out : out std_logic; + eth_nAEN_out : out std_logic; + eth_nBE_out : out std_logic_vector(3 downto 0); + + tx_data_in : in std_logic_vector( interface_width_g-1 downto 0 ); + tx_data_valid_in : in std_logic; + tx_re_out : out std_logic; + rx_re_in : in std_logic; + rx_data_out : out std_logic_vector( interface_width_g-1 downto 0 ); + rx_data_valid_out : out std_logic; + target_MAC_in : in std_logic_vector( 47 downto 0 ); + new_tx_in : in std_logic; + tx_len_in : in std_logic_vector( tx_len_w_c-1 downto 0 ); + tx_frame_type_in : in std_logic_vector( 15 downto 0 ); + new_rx_out : out std_logic; + rx_len_out : out std_logic_vector( tx_len_w_c-1 downto 0 ); + rx_frame_type_out : out std_logic_vector( 15 downto 0 ); + rx_erroneous_out : out std_logic; + ready_out : out std_logic; + fatal_error_out : out std_logic + ); + +end lan91c111_controller; + + +architecture structural of lan91c111_controller is + + signal register_addrs : std_logic_vector( (submodules_c+1) * real_addr_width_c - 1 downto 0 ); + signal config_datas : std_logic_vector( (submodules_c+1) * lan91_data_width_c - 1 downto 0 ); + signal config_nBEs : std_logic_vector( (submodules_c+1) * 4 - 1 downto 0); + signal read_not_writes : std_logic_vector( submodules_c downto 0 ); + signal configs_valid : std_logic_vector( submodules_c downto 0 ); + signal data_to_submodules : std_logic_vector( lan91_data_width_c-1 downto 0 ); + signal data_to_sb_valid : std_logic; + signal busy_to_submodules : std_logic; + + signal comm_reqs : std_logic_vector( submodules_c-1 downto 0 ); + signal comm_grants : std_logic_vector( submodules_c-1 downto 0 ); + + signal init_ready : std_logic; + signal interrupt : std_logic; + + signal tx_data_send_comm : std_logic_vector( lan91_data_width_c-1 downto 0 ); + signal tx_data_valid_send_comm : std_logic; + signal tx_re_comm_send : std_logic; + + signal rx_data_comm_read : std_logic_vector( lan91_data_width_c-1 downto 0 ); + signal rx_data_valid_comm_read : std_logic; + signal rx_re_read_comm : std_logic; + signal tx_ready_int_send : std_logic; + signal rx_waiting_int_read : std_logic; + + signal rx_data_tmp : std_logic_vector(lan91_data_width_c-1 downto 0); + + +------------------------------------------------------------------------------- +begin -- structural +------------------------------------------------------------------------------- + + assert enable_rx_g = '1' or enable_tx_g = '1' report "You probably want to enable at least either tx or rx..." severity failure; + assert interface_width_g = 32 or interface_width_g = 16 report "Data interface width has to be 32 or 16" severity failure; + + comm_module: entity work.lan91c111_comm_module + port map ( + clk => clk, + rst_n => rst_n, + comm_requests_in => comm_reqs, + comm_grants_out => comm_grants, + interrupt_out => interrupt, + init_ready_in => init_ready, + register_addrs_in => register_addrs, + config_datas_in => config_datas, + config_nBEs_in => config_nBEs, + read_not_write_in => read_not_writes, + configs_valid_in => configs_valid, + data_to_submodules_out => data_to_submodules, + data_to_sb_valid_out => data_to_sb_valid, + busy_to_submodules_out => busy_to_submodules, + eth_data_inout => eth_data_inout, + eth_addr_out => eth_addr_out, + eth_interrupt_in => eth_interrupt_in, + eth_read_out => eth_read_out, + eth_write_out => eth_write_out, + eth_nADS_out => eth_nADS_out, + eth_nAEN_out => eth_nAEN_out, + eth_nBE_out => eth_nBE_out + ); + + init_module: entity work.lan91c111_init_module + generic map ( + enable_tx_g => enable_tx_g, + enable_rx_g => enable_rx_g) + port map ( + clk => clk, + rst_n => rst_n, + ready_out => init_ready, + reg_addr_out => register_addrs( (submodules_c+1)*real_addr_width_c - 1 downto submodules_c*real_addr_width_c ), + config_data_out => config_datas( (submodules_c+1)*lan91_data_width_c - 1 downto submodules_c*lan91_data_width_c ), + nBE_out => config_nBEs( (submodules_c+1)*4 - 1 downto submodules_c*4 ), + read_not_write_out => read_not_writes( submodules_c ), + config_valid_out => configs_valid( submodules_c ), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules + ); + + ready_out <= init_ready; + + + enable_tx: if enable_tx_g = '1' generate + + tx_if_32bit: if interface_width_g = 32 generate + send_module: entity work.lan91c111_send_module + generic map ( + mode_16bit_g => 0) + port map ( + clk => clk, + rst_n => rst_n, + tx_completed_in => tx_ready_int_send, + comm_req_out => comm_reqs(2), + comm_grant_in => comm_grants(2), + reg_addr_out => register_addrs( 3*real_addr_width_c-1 downto 2*real_addr_width_c ), + config_data_out => config_datas( 3*lan91_data_width_c-1 downto 2*lan91_data_width_c ), + config_nBE_out => config_nBEs( 3*4-1 downto 2*4 ), + read_not_write_out => read_not_writes(2), + config_valid_out => configs_valid(2), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + tx_data_in => tx_data_in, + tx_data_valid_in => tx_data_valid_in, + tx_re_out => tx_re_out, + tx_MAC_addr_in => target_MAC_in, + new_tx_in => new_tx_in, + tx_len_in => tx_len_in, + tx_frame_type_in => tx_frame_type_in + ); + end generate tx_if_32bit; + + tx_if_16bit: if interface_width_g = 16 generate + send_module: entity work.lan91c111_send_module + generic map ( + mode_16bit_g => 1) + port map ( + clk => clk, + rst_n => rst_n, + tx_completed_in => tx_ready_int_send, + comm_req_out => comm_reqs(2), + comm_grant_in => comm_grants(2), + reg_addr_out => register_addrs( 3*real_addr_width_c-1 downto 2*real_addr_width_c ), + config_data_out => config_datas( 3*lan91_data_width_c-1 downto 2*lan91_data_width_c ), + config_nBE_out => config_nBEs( 3*4-1 downto 2*4 ), + read_not_write_out => read_not_writes(2), + config_valid_out => configs_valid(2), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + tx_data_in => x"0000" & tx_data_in, + tx_data_valid_in => tx_data_valid_in, + tx_re_out => tx_re_out, + tx_MAC_addr_in => target_MAC_in, + new_tx_in => new_tx_in, + tx_len_in => tx_len_in, + tx_frame_type_in => tx_frame_type_in + ); + end generate tx_if_16bit; + + + end generate enable_tx; + + disable_tx: if enable_tx_g = '0' generate + comm_reqs(2) <= '0'; + end generate disable_tx; + + int_handler_module: entity work.lan91c111_interrupt_handler + port map ( + clk => clk, + rst_n => rst_n, + interrupt_in => eth_interrupt_in, + comm_req_out => comm_reqs(0), + comm_grant_in => comm_grants(0), + rx_waiting_out => rx_waiting_int_read, + tx_ready_out => tx_ready_int_send, + reg_addr_out => register_addrs( real_addr_width_c-1 downto 0 ), + config_data_out => config_datas( lan91_data_width_c-1 downto 0 ), + config_nBE_out => config_nBEs( 3 downto 0 ), + read_not_write_out => read_not_writes(0), + config_valid_out => configs_valid(0), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules + ); + + enable_rx: if enable_rx_g = '1' generate + + rx_if_32bit: if interface_width_g = 32 generate + read_module: entity work.lan91c111_read_module + generic map ( + mode_16bit_g => 0) + port map ( + clk => clk, + rst_n => rst_n, + rx_waiting_in => rx_waiting_int_read, + reg_addr_out => register_addrs( 2*real_addr_width_c-1 downto real_addr_width_c ), + config_data_out => config_datas( 2*lan91_data_width_c-1 downto lan91_data_width_c ), + nBE_out => config_nBEs( 2*4-1 downto 4), + read_not_write_out => read_not_writes(1), + config_valid_out => configs_valid(1), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + comm_req_out => comm_reqs(1), + comm_grant_in => comm_grants(1), + rx_data_out => rx_data_out, + rx_data_valid_out => rx_data_valid_out, + rx_re_in => rx_re_in, + new_rx_out => new_rx_out, + rx_len_out => rx_len_out, + frame_type_out => rx_frame_type_out, + rx_erroneous_out => rx_erroneous_out, + fatal_error_out => fatal_error_out + ); + end generate rx_if_32bit; + + rx_if_16bit: if interface_width_g = 16 generate + read_module: entity work.lan91c111_read_module + generic map ( + mode_16bit_g => 1) + port map ( + clk => clk, + rst_n => rst_n, + rx_waiting_in => rx_waiting_int_read, + reg_addr_out => register_addrs( 2*real_addr_width_c-1 downto real_addr_width_c ), + config_data_out => config_datas( 2*lan91_data_width_c-1 downto lan91_data_width_c ), + nBE_out => config_nBEs( 2*4-1 downto 4), + read_not_write_out => read_not_writes(1), + config_valid_out => configs_valid(1), + data_from_comm_in => data_to_submodules, + data_from_comm_valid_in => data_to_sb_valid, + comm_busy_in => busy_to_submodules, + comm_req_out => comm_reqs(1), + comm_grant_in => comm_grants(1), + rx_data_out => rx_data_tmp, + rx_data_valid_out => rx_data_valid_out, + rx_re_in => rx_re_in, + new_rx_out => new_rx_out, + rx_len_out => rx_len_out, + frame_type_out => rx_frame_type_out, + rx_erroneous_out => rx_erroneous_out, + fatal_error_out => fatal_error_out + ); + rx_data_out <= rx_data_tmp(15 downto 0); + end generate rx_if_16bit; + + end generate enable_rx; + + disable_rx: if enable_rx_g = '0' generate + comm_reqs(1) <= '0'; + end generate disable_rx; + +end structural; Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/doc/readme.txt =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/doc/readme.txt (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/doc/readme.txt (revision 34) @@ -0,0 +1,23 @@ +Simple controller for SMSC LAN91C111. Uses the same interface as +DM9000A controller and can be connected to the UDP/IP controller +exactly in the same way. + +LAN91C111 was much more complex to configure and use than DM9000A, +thus the area usage may be somewhat larger. I tried to compensate for +extra complexity by simplifying the structures I could simplify. + +You can disable either rx or tx if you don't need them. This is recommended +to avoid unneeded interrupts and to reduce area usage in case they are not +needed. + +This has been tested for both send and receive operations with +different packet sizes, but simultaneous tx and rx operations may +hang the chip. This is a problem within the chip. + +Also, the chip cannot correctly transmit packets smaller than 66 bytes. +The workaround is to pad them but this should be done on MAC level (i.e., +by the chip) which cannot be done correctly because we cannot override +the packet size field generated by the chip. + +Due to the numerous problems and instability, I strongly recommend not +using LAN91C111 if not absolutely necessary. Index: funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/ip-xact/readme.txt =================================================================== --- funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/ip-xact/readme.txt (nonexistent) +++ funbase_ip_library/trunk/TUT/ip.hwp.interface/eth_lan91c111_ctrl/1.0/ip-xact/readme.txt (revision 34) @@ -0,0 +1,2 @@ +IP-XACTs available for UDP/IP + LAN91C111 CTRL combination, located +in UDP/IP directory.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.