Compare commits
14 Commits
18b4213ed0
...
a9039a175c
Author | SHA1 | Date | |
---|---|---|---|
a9039a175c | |||
4a39c3d638 | |||
d1150fb7db | |||
d1e0143c9d | |||
1bcddf4273 | |||
afb545cd02 | |||
4e39e3b371 | |||
a2edc540b2 | |||
6f8bb7ba54 | |||
76eaff20fd | |||
37714d5c2d | |||
ef6b6378f8 | |||
22b7d99b1f | |||
97d0905c08 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
vunit_out
|
@ -18,7 +18,13 @@ use work.bench_pkg.all;
|
||||
library trashernet;
|
||||
use trashernet.trashernet_pkg.all;
|
||||
|
||||
library vunit_lib;
|
||||
context vunit_lib.vunit_context;
|
||||
|
||||
entity bench_trashernet_mac is
|
||||
generic(
|
||||
runner_cfg : string
|
||||
);
|
||||
end entity bench_trashernet_mac;
|
||||
|
||||
architecture bench of bench_trashernet_mac is
|
||||
@ -37,6 +43,8 @@ architecture bench of bench_trashernet_mac is
|
||||
|
||||
constant TEST_BENCH_LOOPBACK : boolean := true;
|
||||
|
||||
signal mac_tx_start : std_logic := '0';
|
||||
|
||||
begin
|
||||
trashernet_phy_cdc_inst : entity trashernet.trashernet_phy_cdc
|
||||
generic map(
|
||||
@ -144,6 +152,8 @@ begin
|
||||
|
||||
mac_tx : process is
|
||||
begin
|
||||
wait on mac_tx_start;
|
||||
|
||||
mac_in.tx_mac_data <= x"11";
|
||||
mac_in.tx_header.mac_destination <= (x"12", x"23", x"34", x"45", x"56", x"67");
|
||||
mac_in.tx_header.mac_source <= (x"a2", x"a3", x"a4", x"a5", x"a6", x"a7");
|
||||
@ -159,8 +169,27 @@ begin
|
||||
wait until rising_edge(mac_out.tx_mac_data_ack);
|
||||
wait until rising_edge(clk);
|
||||
mac_in.tx_mac_data_en <= '0';
|
||||
|
||||
wait;
|
||||
end process mac_tx;
|
||||
|
||||
test : process is
|
||||
begin
|
||||
wait for 1 ns;
|
||||
|
||||
test_runner_setup(runner, runner_cfg);
|
||||
|
||||
while test_suite loop
|
||||
|
||||
if run("mac_tx_rx_simple") then
|
||||
mac_tx_start <= not mac_tx_start;
|
||||
wait on mac_out.rx_mac_crc_ok, mac_out.rx_mac_crc_error for 1 ms;
|
||||
assert mac_out.rx_mac_crc_ok = '1' report "Did not receive CRC OK" severity error;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
wait for 1 ns;
|
||||
wait until rising_edge(clk);
|
||||
|
||||
test_runner_cleanup(runner);
|
||||
end process test;
|
||||
|
||||
end architecture bench;
|
||||
|
7
demo/lattice_brevia2/.gitignore
vendored
Normal file
7
demo/lattice_brevia2/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
impl1/
|
||||
*.ccl
|
||||
.recovery
|
||||
.run_manager.ini
|
||||
.setting.ini
|
||||
.spread_sheet.ini
|
||||
.spreadsheet_view.ini
|
112
demo/lattice_brevia2/ip/pll0.vhd
Normal file
112
demo/lattice_brevia2/ip/pll0.vhd
Normal file
@ -0,0 +1,112 @@
|
||||
-- VHDL netlist generated by SCUBA Diamond (64-bit) 3.12.0.240.2
|
||||
-- Module Version: 5.7
|
||||
--/usr/local/diamond/3.12/ispfpga/bin/lin64/scuba -w -n pll0 -lang vhdl -synth lse -arch mg5a00 -type pll -fin 50 -phase_cntl STATIC -fclkop 140 -fclkop_tol 0.0 -fb_mode CLOCKTREE -noclkos -noclkok -norst -noclkok2
|
||||
|
||||
-- Sat Jan 22 20:39:11 2022
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
-- synopsys translate_off
|
||||
library xp2;
|
||||
use xp2.components.all;
|
||||
-- synopsys translate_on
|
||||
|
||||
entity pll0 is
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
CLKOP : out std_logic;
|
||||
LOCK : out std_logic);
|
||||
end pll0;
|
||||
|
||||
architecture Structure of pll0 is
|
||||
|
||||
-- internal signal declarations
|
||||
signal CLKOP_t : std_logic;
|
||||
signal scuba_vlo : std_logic;
|
||||
|
||||
-- local component declarations
|
||||
component VLO
|
||||
port(Z : out std_logic);
|
||||
end component;
|
||||
component EPLLD1
|
||||
-- synopsys translate_off
|
||||
generic(CLKOK_BYPASS : in String; CLKOS_BYPASS : in String;
|
||||
CLKOP_BYPASS : in String; DUTY : in Integer;
|
||||
PHASEADJ : in String; PHASE_CNTL : in String;
|
||||
CLKOK_DIV : in Integer; CLKFB_DIV : in Integer;
|
||||
CLKOP_DIV : in Integer; CLKI_DIV : in Integer);
|
||||
-- synopsys translate_on
|
||||
port(CLKI : in std_logic; CLKFB : in std_logic; RST : in std_logic;
|
||||
RSTK : in std_logic; DPAMODE : in std_logic; DRPAI3 : in std_logic;
|
||||
DRPAI2 : in std_logic; DRPAI1 : in std_logic; DRPAI0 : in std_logic;
|
||||
DFPAI3 : in std_logic; DFPAI2 : in std_logic; DFPAI1 : in std_logic;
|
||||
DFPAI0 : in std_logic; PWD : in std_logic; CLKOP : out std_logic;
|
||||
CLKOS : out std_logic; CLKOK : out std_logic; LOCK : out std_logic;
|
||||
CLKINTFB : out std_logic);
|
||||
end component;
|
||||
attribute CLKOK_BYPASS : string;
|
||||
attribute CLKOS_BYPASS : string;
|
||||
attribute FREQUENCY_PIN_CLKOP : string;
|
||||
attribute CLKOP_BYPASS : string;
|
||||
attribute PHASE_CNTL : string;
|
||||
attribute DUTY : string;
|
||||
attribute PHASEADJ : string;
|
||||
attribute FREQUENCY_PIN_CLKI : string;
|
||||
attribute CLKOK_DIV : string;
|
||||
attribute CLKOP_DIV : string;
|
||||
attribute CLKFB_DIV : string;
|
||||
attribute CLKI_DIV : string;
|
||||
attribute FIN : string;
|
||||
attribute CLKOK_BYPASS of PLLInst_0 : label is "DISABLED";
|
||||
attribute CLKOS_BYPASS of PLLInst_0 : label is "DISABLED";
|
||||
attribute FREQUENCY_PIN_CLKOP of PLLInst_0 : label is "140.000000";
|
||||
attribute CLKOP_BYPASS of PLLInst_0 : label is "DISABLED";
|
||||
attribute PHASE_CNTL of PLLInst_0 : label is "STATIC";
|
||||
attribute DUTY of PLLInst_0 : label is "8";
|
||||
attribute PHASEADJ of PLLInst_0 : label is "0.0";
|
||||
attribute FREQUENCY_PIN_CLKI of PLLInst_0 : label is "50.000000";
|
||||
attribute CLKOK_DIV of PLLInst_0 : label is "2";
|
||||
attribute CLKOP_DIV of PLLInst_0 : label is "4";
|
||||
attribute CLKFB_DIV of PLLInst_0 : label is "14";
|
||||
attribute CLKI_DIV of PLLInst_0 : label is "5";
|
||||
attribute FIN of PLLInst_0 : label is "50.000000";
|
||||
attribute syn_keep : boolean;
|
||||
attribute NGD_DRC_MASK : integer;
|
||||
attribute NGD_DRC_MASK of Structure : architecture is 1;
|
||||
|
||||
begin
|
||||
-- component instantiation statements
|
||||
scuba_vlo_inst : VLO
|
||||
port map(Z => scuba_vlo);
|
||||
|
||||
PLLInst_0 : EPLLD1
|
||||
-- synopsys translate_off
|
||||
generic map(CLKOK_BYPASS => "DISABLED", CLKOS_BYPASS => "DISABLED",
|
||||
CLKOP_BYPASS => "DISABLED", PHASE_CNTL => "STATIC", DUTY => 8,
|
||||
PHASEADJ => "0.0", CLKOK_DIV => 2, CLKOP_DIV => 4, CLKFB_DIV => 14,
|
||||
CLKI_DIV => 5)
|
||||
-- synopsys translate_on
|
||||
port map(CLKI => CLK, CLKFB => CLKOP_t, RST => scuba_vlo,
|
||||
RSTK => scuba_vlo, DPAMODE => scuba_vlo, DRPAI3 => scuba_vlo,
|
||||
DRPAI2 => scuba_vlo, DRPAI1 => scuba_vlo, DRPAI0 => scuba_vlo,
|
||||
DFPAI3 => scuba_vlo, DFPAI2 => scuba_vlo, DFPAI1 => scuba_vlo,
|
||||
DFPAI0 => scuba_vlo, PWD => scuba_vlo, CLKOP => CLKOP_t,
|
||||
CLKOS => open, CLKOK => open, LOCK => LOCK, CLKINTFB => open);
|
||||
|
||||
CLKOP <= CLKOP_t;
|
||||
end Structure;
|
||||
|
||||
-- synopsys translate_off
|
||||
library xp2;
|
||||
configuration Structure_CON of pll0 is
|
||||
for Structure
|
||||
for all : VLO
|
||||
use entity xp2.VLO(V);
|
||||
end for;
|
||||
for all : EPLLD1
|
||||
use entity xp2.EPLLD1(V);
|
||||
end for;
|
||||
end for;
|
||||
end Structure_CON;
|
||||
|
||||
-- synopsys translate_on
|
47
demo/lattice_brevia2/mac_test/mac_test.ldf
Normal file
47
demo/lattice_brevia2/mac_test/mac_test.ldf
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<BaliProject version="3.2" title="mac_test" device="LFXP2-5E-6TN144C" default_implementation="impl1">
|
||||
<Options/>
|
||||
<Implementation title="impl1" dir="impl1" description="impl1" synthesis="lse" default_strategy="Strategy1">
|
||||
<Options def_top="trashernet.trashernet_eth" lib="work" top="top_mac_test"/>
|
||||
<Source name="../../design/top_mac_test.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="work" top_module="top_mac_test"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/cdc_strobe.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/crc.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/synchronizer.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/trashernet_eth.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/trashernet_mac.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/trashernet_phy.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/trashernet_phy_cdc.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../trashernet/trashernet_pkg.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="trashernet"/>
|
||||
</Source>
|
||||
<Source name="../../ip/pll0.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="work"/>
|
||||
</Source>
|
||||
<Source name="../../design/ledcon.vhd" type="VHDL" type_short="VHDL">
|
||||
<Options lib="work"/>
|
||||
</Source>
|
||||
<Source name="impl1/impl1.xcf" type="Programming Project File" type_short="Programming">
|
||||
<Options/>
|
||||
</Source>
|
||||
<Source name="mac_test.lpf" type="Logic Preference" type_short="LPF">
|
||||
<Options/>
|
||||
</Source>
|
||||
</Implementation>
|
||||
<Strategy name="Strategy1" file="mac_test1.sty"/>
|
||||
</BaliProject>
|
47
demo/lattice_brevia2/mac_test/mac_test.lpf
Normal file
47
demo/lattice_brevia2/mac_test/mac_test.lpf
Normal file
@ -0,0 +1,47 @@
|
||||
BLOCK RESETPATHS ;
|
||||
BLOCK ASYNCPATHS ;
|
||||
LOCATE COMP "clk" SITE "21" ;
|
||||
LOCATE COMP "rst_n" SITE "19" ;
|
||||
LOCATE COMP "rx_p" SITE "94" ;
|
||||
LOCATE COMP "led_n[0]" SITE "37" ;
|
||||
LOCATE COMP "led_n[1]" SITE "38" ;
|
||||
LOCATE COMP "led_n[2]" SITE "39" ;
|
||||
LOCATE COMP "led_n[3]" SITE "40" ;
|
||||
LOCATE COMP "led_n[4]" SITE "43" ;
|
||||
LOCATE COMP "led_n[5]" SITE "44" ;
|
||||
LOCATE COMP "led_n[6]" SITE "45" ;
|
||||
LOCATE COMP "led_n[7]" SITE "46" ;
|
||||
IOBUF PORT "rx_p" IO_TYPE=LVPECL33 ;
|
||||
IOBUF PORT "clk" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "rst_n" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[0]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[1]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[2]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[3]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[4]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[5]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[6]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "debug_data[7]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[0]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[1]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[2]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[3]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[4]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[5]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[6]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "led_n[7]" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "tx_n" IO_TYPE=LVCMOS33 ;
|
||||
IOBUF PORT "tx_p" IO_TYPE=LVCMOS33 ;
|
||||
LOCATE COMP "tx_n" SITE "114" ;
|
||||
LOCATE COMP "tx_p" SITE "116" ;
|
||||
LOCATE COMP "button_n[0]" SITE "54" ;
|
||||
LOCATE COMP "debug_data[0]" SITE "73" ;
|
||||
LOCATE COMP "debug_data[1]" SITE "74" ;
|
||||
LOCATE COMP "debug_data[2]" SITE "77" ;
|
||||
LOCATE COMP "debug_data[3]" SITE "87" ;
|
||||
LOCATE COMP "debug_data[4]" SITE "88" ;
|
||||
LOCATE COMP "debug_data[5]" SITE "89" ;
|
||||
LOCATE COMP "debug_data[6]" SITE "90" ;
|
||||
LOCATE COMP "debug_data[7]" SITE "91" ;
|
||||
BLOCK PATH FROM CLKNET "clk_c" TO CLKNET "clk_phy" ;
|
||||
BLOCK PATH FROM CLKNET "clk_phy" TO CLKNET "clk_c" ;
|
206
demo/lattice_brevia2/mac_test/mac_test1.sty
Normal file
206
demo/lattice_brevia2/mac_test/mac_test1.sty
Normal file
@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE strategy>
|
||||
<Strategy version="1.0" predefined="0" description="" label="Strategy1">
|
||||
<Property name="PROP_BD_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_BD_EdfInBusNameConv" value="None" time="0"/>
|
||||
<Property name="PROP_BD_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_BD_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_BD_ParSearchPath" value="" time="0"/>
|
||||
<Property name="PROP_BIT_AddressBitGen" value="Increment" time="0"/>
|
||||
<Property name="PROP_BIT_AllowReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ByteWideBitMirror" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CapReadBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ConModBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_CreateBitFile" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisRAMResBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_DisableUESBitgen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_DonePinBitGen" value="Pullup" time="0"/>
|
||||
<Property name="PROP_BIT_DoneSigBitGen" value="4" time="0"/>
|
||||
<Property name="PROP_BIT_EnIOBitGen" value="TriStateDuringReConfig" time="0"/>
|
||||
<Property name="PROP_BIT_EnIntOscBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_ExtClockBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_GSREnableBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_GSRRelOnBitGen" value="DoneIn" time="0"/>
|
||||
<Property name="PROP_BIT_GranTimBitGen" value="0" time="0"/>
|
||||
<Property name="PROP_BIT_IOTriRelBitGen" value="Cycle 2" time="0"/>
|
||||
<Property name="PROP_BIT_JTAGEnableBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_LenBitsBitGen" value="24" time="0"/>
|
||||
<Property name="PROP_BIT_MIFFileBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_NoHeader" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen" value="Bit File (Binary)" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatBitGen_REF" value="Bit File (Binary)" time="0"/>
|
||||
<Property name="PROP_BIT_OutFormatPromGen" value="Intel Hex 32-bit" time="0"/>
|
||||
<Property name="PROP_BIT_ParityCheckBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_ReadBackBitGen" value="Flash" time="0"/>
|
||||
<Property name="PROP_BIT_ReadCaptureBitGen" value="Disable" time="0"/>
|
||||
<Property name="PROP_BIT_RemZeroFramesBitGen" value="False" time="0"/>
|
||||
<Property name="PROP_BIT_RunDRCBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SearchPthBitGen" value="" time="0"/>
|
||||
<Property name="PROP_BIT_StartUpClkBitGen" value="Cclk" time="0"/>
|
||||
<Property name="PROP_BIT_SynchIOBitGen" value="True" time="0"/>
|
||||
<Property name="PROP_BIT_SysClockConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_SysConBitGen" value="Reset" time="0"/>
|
||||
<Property name="PROP_BIT_UFMOrder" value="Normal" time="0"/>
|
||||
<Property name="PROP_BIT_WaitStTimBitGen" value="5" time="0"/>
|
||||
<Property name="PROP_IOTIMING_AllSpeed" value="False" time="0"/>
|
||||
<Property name="PROP_LST_AllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_LST_CarryChain" value="True" time="0"/>
|
||||
<Property name="PROP_LST_CarryChainLength" value="0" time="0"/>
|
||||
<Property name="PROP_LST_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_LST_DSPStyle" value="DSP" time="0"/>
|
||||
<Property name="PROP_LST_DSPUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_DecodeUnreachableStates" value="False" time="0"/>
|
||||
<Property name="PROP_LST_DisableDistRam" value="False" time="0"/>
|
||||
<Property name="PROP_LST_EBRUtil" value="100" time="0"/>
|
||||
<Property name="PROP_LST_EdfFrequency" value="200" time="0"/>
|
||||
<Property name="PROP_LST_EdfHardtimer" value="Enable" time="0"/>
|
||||
<Property name="PROP_LST_EdfInLibPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_EdfInRemLoc" value="Off" time="0"/>
|
||||
<Property name="PROP_LST_EdfMemPath" value="" time="0"/>
|
||||
<Property name="PROP_LST_FIXGATEDCLKS" value="True" time="0"/>
|
||||
<Property name="PROP_LST_FSMEncodeStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ForceGSRInfer" value="No" time="0"/>
|
||||
<Property name="PROP_LST_IOInsertion" value="True" time="0"/>
|
||||
<Property name="PROP_LST_InterFileDump" value="False" time="0"/>
|
||||
<Property name="PROP_LST_LoopLimit" value="1950" time="0"/>
|
||||
<Property name="PROP_LST_MaxFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_LST_MuxStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_NumCriticalPaths" value="" time="0"/>
|
||||
<Property name="PROP_LST_OptimizeGoal" value="Timing" time="0"/>
|
||||
<Property name="PROP_LST_PropagatConst" value="True" time="0"/>
|
||||
<Property name="PROP_LST_RAMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_ROMStyle" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_RemoveDupRegs" value="True" time="0"/>
|
||||
<Property name="PROP_LST_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_LST_ResourceShare" value="True" time="0"/>
|
||||
<Property name="PROP_LST_UseIOReg" value="Auto" time="0"/>
|
||||
<Property name="PROP_LST_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_LST_VHDL2008" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_MAPSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_CheckUnconstrainedPaths" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_FullName" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RouteEstAlogtithm" value="0" time="0"/>
|
||||
<Property name="PROP_MAPSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_MAPSTA_WordCasePaths" value="1" time="0"/>
|
||||
<Property name="PROP_MAP_IgnorePreErr" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MAPIORegister" value="Auto" time="0"/>
|
||||
<Property name="PROP_MAP_MAPInferGSR" value="True" time="0"/>
|
||||
<Property name="PROP_MAP_MapModArgs" value="" time="0"/>
|
||||
<Property name="PROP_MAP_OvermapDevice" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_PackLogMapDes" value="" time="0"/>
|
||||
<Property name="PROP_MAP_RegRetiming" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SigCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_SymCrossRef" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDriven" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenNodeRep" value="False" time="0"/>
|
||||
<Property name="PROP_MAP_TimingDrivenPack" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_AnalysisOption" value="Standard Setup and Hold Analysis" time="0"/>
|
||||
<Property name="PROP_PARSTA_AutoTiming" value="True" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedConns" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_CheckUnconstrainedPaths" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_FullName" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_NumUnconstrainedPaths" value="0" time="0"/>
|
||||
<Property name="PROP_PARSTA_ReportStyle" value="Verbose Timing Report" time="0"/>
|
||||
<Property name="PROP_PARSTA_RptAsynTimLoop" value="False" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForHoldAnalysis" value="m" time="0"/>
|
||||
<Property name="PROP_PARSTA_SpeedForSetupAnalysis" value="default" time="0"/>
|
||||
<Property name="PROP_PARSTA_WordCasePaths" value="10" time="0"/>
|
||||
<Property name="PROP_PAR_CrDlyStFileParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_DisableTDParDes" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_EffortParDes" value="5" time="0"/>
|
||||
<Property name="PROP_PAR_MultiSeedSortMode" value="Worst Slack" time="0"/>
|
||||
<Property name="PROP_PAR_NewRouteParDes" value="NBR" time="0"/>
|
||||
<Property name="PROP_PAR_PARClockSkew" value="Off" time="0"/>
|
||||
<Property name="PROP_PAR_PARModArgs" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParMultiNodeList" value="" time="0"/>
|
||||
<Property name="PROP_PAR_ParRunPlaceOnly" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_PlcIterParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_PlcStCostTblParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_PrefErrorOut" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RemoveDir" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_RouteDlyRedParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutePassParDes" value="6" time="0"/>
|
||||
<Property name="PROP_PAR_RouteResOptParDes" value="0" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDP" value="Auto" time="0"/>
|
||||
<Property name="PROP_PAR_RoutingCDR" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_RunParWithTrce" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_RunTimeReduction" value="True" time="0"/>
|
||||
<Property name="PROP_PAR_SaveBestRsltParDes" value="1" time="0"/>
|
||||
<Property name="PROP_PAR_StopZero" value="False" time="0"/>
|
||||
<Property name="PROP_PAR_parHold" value="On" time="0"/>
|
||||
<Property name="PROP_PAR_parPathBased" value="Off" time="0"/>
|
||||
<Property name="PROP_PRE_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_PRE_EdfArrayBoundsCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfAutoResOfRam" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfClockDomainCross" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfDSPAcrossHie" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfFullCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfIgnoreRamRWCol" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfMissConstraint" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfNetFanout" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfParaCase" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfReencodeFSM" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfTimingViolation" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_EdfUseSafeFSM" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_EdfVlog2001" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynComArea" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynCritcal" value="3" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFSM" value="Auto" time="0"/>
|
||||
<Property name="PROP_PRE_VSynFreq" value="200" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGSR" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynGatedClk" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynIOPad" value="False" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_PRE_VSynOutPref" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRepClkFreq" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynRetime" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTimSum" value="10" time="0"/>
|
||||
<Property name="PROP_PRE_VSynTransform" value="True" time="0"/>
|
||||
<Property name="PROP_PRE_VSyninpd" value="0" time="0"/>
|
||||
<Property name="PROP_PRE_VSynoutd" value="0" time="0"/>
|
||||
<Property name="PROP_SYN_ClockConversion" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_CmdLineArgs" value="" time="0"/>
|
||||
<Property name="PROP_SYN_DisableRegisterRep" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfAllowDUPMod" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArea" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfArrangeVHDLFiles" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfDefEnumEncode" value="Default" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFanout" value="1000" time="0"/>
|
||||
<Property name="PROP_SYN_EdfFrequency" value="200" time="0"/>
|
||||
<Property name="PROP_SYN_EdfGSR" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfInsertIO" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumCritPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfNumStartEnd" value="" time="0"/>
|
||||
<Property name="PROP_SYN_EdfOutNetForm" value="None" time="0"/>
|
||||
<Property name="PROP_SYN_EdfPushTirstates" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfResSharing" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfRunRetiming" value="Pipelining Only" time="0"/>
|
||||
<Property name="PROP_SYN_EdfSymFSM" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_EdfUnconsClk" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_EdfVerilogInput" value="Verilog 2001" time="0"/>
|
||||
<Property name="PROP_SYN_ExportSetting" value="No" time="0"/>
|
||||
<Property name="PROP_SYN_LibPath" value="" time="0"/>
|
||||
<Property name="PROP_SYN_ResolvedMixedDrivers" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UpdateCompilePtTimData" value="False" time="0"/>
|
||||
<Property name="PROP_SYN_UseLPF" value="True" time="0"/>
|
||||
<Property name="PROP_SYN_VHDL2008" value="True" time="0"/>
|
||||
<Property name="PROP_THERMAL_DefaultFreq" value="0" time="0"/>
|
||||
<Property name="PROP_TIM_MaxDelSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_MinSpeedGrade" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_ModPreSimDes" value="" time="0"/>
|
||||
<Property name="PROP_TIM_NegStupHldTim" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenPUR" value="True" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimGenX" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TimSimHierSep" value="" time="0"/>
|
||||
<Property name="PROP_TIM_TransportModeOfPathDelay" value="False" time="0"/>
|
||||
<Property name="PROP_TIM_TrgtSpeedGrade" value="" time="0"/>
|
||||
<Property name="PROP_TIM_WriteVerboseNetlist" value="False" time="0"/>
|
||||
<Property name="PROP_TMCHK_EnableCheck" value="True" time="0"/>
|
||||
</Strategy>
|
77
design/ledcon.vhd
Normal file
77
design/ledcon.vhd
Normal file
@ -0,0 +1,77 @@
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TRASHERNET - A Trashy Ethernet Stack for FPGAs --
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- ledcon.vhd : Simple debug LED helper
|
||||
-- To blink or not blink.
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- Author : Markus Koch <markus@notsyncing.net>
|
||||
-- Contributors : None
|
||||
-- License : Mozilla Public License (MPL) Version 2
|
||||
-- -------------------------------------------------------------------------- --
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity ledcon is
|
||||
generic(
|
||||
F_CLK : integer;
|
||||
BLINK : boolean_vector
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
sig : in std_logic_vector;
|
||||
led_n : out std_logic_vector
|
||||
);
|
||||
end entity ledcon;
|
||||
|
||||
architecture RTL of ledcon is
|
||||
constant MS_CNT_MAX : integer := integer(round(real(F_CLK) * (1.0 * 10.0 ** (-3))));
|
||||
signal ms_cnt : integer range 0 to MS_CNT_MAX;
|
||||
signal ms_tick : std_logic;
|
||||
begin
|
||||
mstimer : process(clk, rst) is
|
||||
begin
|
||||
if rst then
|
||||
ms_cnt <= MS_CNT_MAX;
|
||||
elsif rising_edge(clk) then
|
||||
if (ms_cnt = 0) then
|
||||
ms_cnt <= MS_CNT_MAX;
|
||||
else
|
||||
ms_cnt <= ms_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process mstimer;
|
||||
ms_tick <= '1' when ms_cnt = 0 else '0';
|
||||
|
||||
ledcongen : for i in sig'low to sig'high generate
|
||||
ledblock : block
|
||||
constant LED_CNT_MAX : integer := 50; -- on time, in ms
|
||||
constant LED_CNT_MIN : integer := -50; -- off time, in ms
|
||||
signal led_cnt : integer range LED_CNT_MIN to LED_CNT_MAX;
|
||||
begin
|
||||
ledgen : if BLINK(i) generate
|
||||
ledproc : process(clk, rst) is
|
||||
begin
|
||||
if rst then
|
||||
led_cnt <= LED_CNT_MIN;
|
||||
elsif rising_edge(clk) then
|
||||
if (led_cnt = LED_CNT_MIN) then
|
||||
if sig(i) then
|
||||
led_cnt <= LED_CNT_MAX;
|
||||
end if;
|
||||
elsif ms_tick then
|
||||
led_cnt <= led_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process ledproc;
|
||||
led_n(i) <= '0' when led_cnt > 0 else '1';
|
||||
else generate
|
||||
led_n(i) <= not sig(i);
|
||||
end generate ledgen;
|
||||
end block ledblock;
|
||||
end generate ledcongen;
|
||||
|
||||
end architecture RTL;
|
212
design/top_mac_test.vhd
Normal file
212
design/top_mac_test.vhd
Normal file
@ -0,0 +1,212 @@
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- TRASHERNET - A Trashy Ethernet Stack for FPGAs --
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- top_mac_test.vhd: Test design to verify the functionality of the MAC core
|
||||
-- Sends a broadcast with 100 decrementing numbers every 250 ms or when a
|
||||
-- button is pushed. It will also directly reply with that content to any
|
||||
-- packet addressed to us.
|
||||
--
|
||||
-- Target: Lattice Brevia 2 (LFXP2-5E)
|
||||
-- -------------------------------------------------------------------------- --
|
||||
-- Author : Markus Koch <markus@notsyncing.net>
|
||||
-- Contributors : None
|
||||
-- License : Mozilla Public License (MPL) Version 2
|
||||
-- -------------------------------------------------------------------------- --
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use ieee.math_real.all;
|
||||
|
||||
library trashernet;
|
||||
use trashernet.trashernet_pkg.all;
|
||||
|
||||
entity top_mac_test is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst_n : in std_logic;
|
||||
rx_p : in std_logic;
|
||||
tx_p : out std_logic;
|
||||
tx_n : out std_logic;
|
||||
led_n : out std_logic_vector(7 downto 0);
|
||||
button_n : in std_logic_vector(3 downto 0);
|
||||
debug_data : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity top_mac_test;
|
||||
|
||||
architecture rtl of top_mac_test is
|
||||
component pll0
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
CLKOP : out std_logic;
|
||||
LOCK : out std_logic
|
||||
);
|
||||
end component pll0;
|
||||
|
||||
constant F_CLK : integer := 50000000;
|
||||
constant F_CLK_PHY : integer := 140000000;
|
||||
|
||||
constant LED_BLINK : boolean_vector(led_n'range) := (
|
||||
6 downto 2 => true,
|
||||
others => false
|
||||
);
|
||||
|
||||
constant ETH_CONFIG : configuration_t := (
|
||||
mac_address => (x"00", x"ff", x"ff", x"11", x"22", x"33")
|
||||
);
|
||||
|
||||
signal rst : std_logic;
|
||||
signal clk_phy : std_logic;
|
||||
signal phy_pll_lock : std_logic;
|
||||
|
||||
signal led_sig : std_logic_vector(led_n'range);
|
||||
|
||||
signal phy_out : phy_out_t;
|
||||
signal phy_in : phy_in_t;
|
||||
|
||||
signal mac_out : mac_out_t;
|
||||
signal mac_in : mac_in_t;
|
||||
|
||||
type status_t is (IDLE, TX, WAITDONE);
|
||||
signal state : status_t;
|
||||
constant BYTE_CNT_MAX : integer := 100;
|
||||
signal byte_cnt : integer range 0 to BYTE_CNT_MAX;
|
||||
|
||||
signal button_n_sync : std_logic_vector(button_n'range);
|
||||
signal button : std_logic_vector(button_n'range);
|
||||
|
||||
constant TMO_MAX : integer := integer(round((real(F_CLK) * 0.25))) - 1;
|
||||
signal tmo : integer range 0 to TMO_MAX;
|
||||
begin
|
||||
trashernet_mac_inst : entity trashernet.trashernet_mac
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
phy_out => phy_out,
|
||||
phy_in => phy_in,
|
||||
mac_out => mac_out,
|
||||
mac_in => mac_in
|
||||
);
|
||||
|
||||
pll0_inst : pll0
|
||||
port map(
|
||||
CLK => clk,
|
||||
CLKOP => clk_phy,
|
||||
LOCK => phy_pll_lock
|
||||
);
|
||||
|
||||
trashernet_phy_cdc_inst : entity trashernet.trashernet_phy_cdc
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
F_CLK_PHY => F_CLK_PHY
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
phy_clk => clk_phy,
|
||||
rst => rst,
|
||||
phy_out => phy_out,
|
||||
phy_in => phy_in,
|
||||
rx_p => rx_p,
|
||||
tx_p => tx_p,
|
||||
tx_n => tx_n
|
||||
);
|
||||
|
||||
reset_sync : process(clk, rst_n) is
|
||||
begin
|
||||
if (rst_n = '0') then
|
||||
rst <= '1';
|
||||
elsif (rising_edge(clk)) then
|
||||
rst <= '0';
|
||||
end if;
|
||||
end process reset_sync;
|
||||
|
||||
ledcon_inst : entity work.ledcon
|
||||
generic map(
|
||||
F_CLK => F_CLK,
|
||||
BLINK => LED_BLINK
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
sig => led_sig,
|
||||
led_n => led_n
|
||||
);
|
||||
|
||||
led_sig <= (
|
||||
0 => phy_pll_lock,
|
||||
1 => phy_out.carrier_detect,
|
||||
2 => phy_out.rx_active,
|
||||
3 => phy_out.rx_error,
|
||||
4 => mac_out.rx_mac_crc_ok,
|
||||
5 => mac_out.rx_mac_crc_error,
|
||||
6 => mac_out.tx_active,
|
||||
7 => '0'
|
||||
);
|
||||
|
||||
synchronizer_inst : entity trashernet.synchronizer
|
||||
generic map(
|
||||
SIZE => 2
|
||||
)
|
||||
port map(
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
data_in => button_n(0),
|
||||
data_out => button_n_sync(0)
|
||||
);
|
||||
|
||||
button <= not button_n_sync;
|
||||
|
||||
receiver : process(clk, rst) is
|
||||
begin
|
||||
if rst then
|
||||
state <= IDLE;
|
||||
mac_in.tx_mac_data_en <= '0';
|
||||
tmo <= 0;
|
||||
elsif rising_edge(clk) then
|
||||
if (tmo /= 0) then
|
||||
tmo <= tmo - 1;
|
||||
end if;
|
||||
case state is
|
||||
when IDLE =>
|
||||
if mac_out.rx_mac_crc_ok then
|
||||
if (mac_out.rx_header.mac_destination = ETH_CONFIG.mac_address) then -- Note: We won't respond to broadcasts!
|
||||
state <= TX;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
mac_in.tx_header.mac_destination <= mac_out.rx_header.mac_source;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (tmo = 0) or (button(0) = '1') then
|
||||
state <= TX;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
mac_in.tx_header.mac_destination <= (others => x"FF");
|
||||
end if;
|
||||
when TX =>
|
||||
tmo <= TMO_MAX;
|
||||
mac_in.tx_header.mac_ethertype <= (x"00", std_logic_vector(to_unsigned(BYTE_CNT_MAX, 8)));
|
||||
mac_in.tx_mac_data_en <= '1';
|
||||
mac_in.tx_mac_data <= std_logic_vector(to_unsigned(byte_cnt, 8));
|
||||
if mac_out.tx_mac_data_ack then
|
||||
if byte_cnt = 1 then
|
||||
mac_in.tx_mac_data_en <= '0';
|
||||
state <= WAITDONE;
|
||||
else
|
||||
byte_cnt <= byte_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
when WAITDONE =>
|
||||
if mac_out.tx_active = '0' then
|
||||
state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
|
||||
end if;
|
||||
end process receiver;
|
||||
|
||||
mac_in.tx_header.mac_source <= ETH_CONFIG.mac_address;
|
||||
|
||||
debug_data(0) <= tx_p;
|
||||
debug_data(1) <= tx_n;
|
||||
|
||||
end architecture rtl;
|
16
run.py
Executable file
16
run.py
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
from vunit import VUnit
|
||||
import os
|
||||
|
||||
library_names = ["trashernet", "bench"]
|
||||
|
||||
|
||||
libs = {}
|
||||
|
||||
vu = VUnit.from_argv()
|
||||
|
||||
for library_name in library_names:
|
||||
libs[library_name] = vu.add_library(library_name)
|
||||
libs[library_name].add_source_files(os.path.join(library_name, "*.vhd"))
|
||||
|
||||
vu.main()
|
@ -54,8 +54,7 @@ begin
|
||||
);
|
||||
|
||||
-- strobify
|
||||
b_toggle_last <= '0' when b_rst
|
||||
else b_toggle when rising_edge(b_clk)
|
||||
;
|
||||
b_toggle_last <= '0' when b_rst else
|
||||
b_toggle when rising_edge(b_clk);
|
||||
b_out <= (b_toggle ?/= b_toggle_last);
|
||||
end architecture rtl;
|
||||
|
@ -32,7 +32,8 @@ entity trashernet_mac is
|
||||
end entity trashernet_mac;
|
||||
|
||||
architecture rtl of trashernet_mac is
|
||||
constant ETH_POLYNOMIAL : std_logic_vector(31 downto 0) := x"04C11DB7";
|
||||
constant ETH_POLYNOMIAL : std_logic_vector(31 downto 0) := x"04C11DB7";
|
||||
constant ETH_FRAME_MIN_LENGTH : integer := 64;
|
||||
|
||||
begin
|
||||
rx : block
|
||||
@ -78,6 +79,7 @@ begin
|
||||
mac_out.rx_mac_crc_ok <= '0';
|
||||
mac_out.rx_mac_header_rcv <= '0';
|
||||
crc_clear <= '0';
|
||||
state <= HEAD;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
mac_out.rx_mac_valid <= '0';
|
||||
@ -134,12 +136,14 @@ begin
|
||||
end block rx;
|
||||
|
||||
tx : block
|
||||
type tx_state_t is (IDLE, HEADER, DATA, TXCRC);
|
||||
type tx_state_t is (IDLE, HEADER, DATA, PAD, TXCRC);
|
||||
signal tx_state : tx_state_t;
|
||||
|
||||
signal sr : byte_vector(0 to mac_in.tx_header.mac_destination'length + mac_in.tx_header.mac_source'length + mac_in.tx_header.mac_ethertype'length - 1);
|
||||
constant BIT_CNT_MAX : integer := sr'high;
|
||||
signal byte_cnt : integer range 0 to BIT_CNT_MAX;
|
||||
signal sr : byte_vector(0 to mac_in.tx_header.mac_destination'length + mac_in.tx_header.mac_source'length + mac_in.tx_header.mac_ethertype'length - 1);
|
||||
constant SR_CNT_MAX : integer := sr'high;
|
||||
signal sr_cnt : integer range 0 to SR_CNT_MAX;
|
||||
constant BYTE_CNT_MAX : integer := ETH_FRAME_MIN_LENGTH - 4; -- Minus four because the CRC is *after* the PAD
|
||||
signal byte_cnt : integer range 0 to BYTE_CNT_MAX;
|
||||
|
||||
signal crc : std_logic_vector(ETH_POLYNOMIAL'range);
|
||||
signal crc_clear : std_logic;
|
||||
@ -162,51 +166,66 @@ begin
|
||||
);
|
||||
|
||||
tx_main : process(clk, rst) is
|
||||
variable more_data : std_logic;
|
||||
begin
|
||||
if rst then
|
||||
mac_out.tx_mac_data_ack <= '0';
|
||||
tx_state <= IDLE;
|
||||
sr_cnt <= 0;
|
||||
byte_cnt <= 0;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
mac_out.tx_mac_data_ack <= '0';
|
||||
crc_valid <= '0';
|
||||
more_data := more_data and mac_in.tx_mac_data_en; -- Latch a short low-pulse on tx_en
|
||||
|
||||
if phy_out.tx_data_ack then
|
||||
sr <= sr(sr'low + 1 to sr'high) & x"00";
|
||||
crc_valid <= '1';
|
||||
if sr_cnt /= 0 then
|
||||
sr_cnt <= sr_cnt - 1;
|
||||
end if;
|
||||
if byte_cnt /= 0 then
|
||||
byte_cnt <= byte_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
case tx_state is
|
||||
when IDLE =>
|
||||
when IDLE => -- Idle + prepare sync header
|
||||
if not phy_out.tx_active and mac_in.tx_mac_data_en then
|
||||
more_data := '1';
|
||||
sr(0 to 7) <= byte_vector'(0 to 6 => x"55", 7 => x"D5");
|
||||
byte_cnt <= 7;
|
||||
sr_cnt <= 7;
|
||||
tx_state <= HEADER;
|
||||
end if;
|
||||
|
||||
when HEADER =>
|
||||
if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- Sync Header TX complete
|
||||
when HEADER => -- Wait for sync header + prepare MAC header
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- Sync Header TX complete
|
||||
sr <= mac_in.tx_header.mac_destination & mac_in.tx_header.mac_source & mac_in.tx_header.mac_ethertype;
|
||||
crc_valid <= '1';
|
||||
byte_cnt <= BIT_CNT_MAX;
|
||||
sr_cnt <= SR_CNT_MAX;
|
||||
tx_state <= DATA;
|
||||
end if;
|
||||
byte_cnt <= BYTE_CNT_MAX;
|
||||
|
||||
when DATA =>
|
||||
if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- MAC Header TX complete
|
||||
if mac_in.tx_mac_data_en then
|
||||
when DATA => -- Wait for MAC header + transmit payload until tx_mac_data_en goes away
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- MAC Header TX complete
|
||||
if more_data then
|
||||
sr(0) <= mac_in.tx_mac_data;
|
||||
mac_out.tx_mac_data_ack <= '1';
|
||||
else
|
||||
sr(0 to 3) <= (crc(7 downto 0), crc(15 downto 8), crc(23 downto 16), crc(31 downto 24));
|
||||
byte_cnt <= 4 - 1;
|
||||
tx_state <= TXCRC;
|
||||
tx_state <= PAD;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when TXCRC =>
|
||||
if (phy_out.tx_data_ack = '1') and (byte_cnt = 0) then -- CRC TX complete
|
||||
when PAD => -- Wait for PADs / last payload byte + prepare CRC
|
||||
if (byte_cnt = 0) then
|
||||
sr(0 to 3) <= (crc(7 downto 0), crc(15 downto 8), crc(23 downto 16), crc(31 downto 24));
|
||||
sr_cnt <= 4 - 1;
|
||||
tx_state <= TXCRC;
|
||||
end if;
|
||||
|
||||
when TXCRC => -- Wait for CRC + jump back to idle
|
||||
if (phy_out.tx_data_ack = '1') and (sr_cnt = 0) then -- CRC TX complete
|
||||
tx_state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
@ -215,6 +234,8 @@ begin
|
||||
phy_in.tx_data_en <= '1' when tx_state /= IDLE else '0';
|
||||
crc_clear <= '1' when tx_state = HEADER else '0';
|
||||
phy_in.tx_data <= sr(sr'low);
|
||||
|
||||
mac_out.tx_active <= phy_out.tx_active;
|
||||
end block tx;
|
||||
|
||||
end architecture rtl;
|
||||
|
@ -56,7 +56,7 @@ begin
|
||||
signal bit_cnt : integer range 0 to 7;
|
||||
|
||||
-- NLP supervision
|
||||
constant NLP_TIMEOUT_CNT_MAX : integer := integer(round(real(F_CLK) * 16.0 * 10.0**(-3))); -- Every 16 ms
|
||||
constant NLP_TIMEOUT_CNT_MAX : integer := integer(round(real(F_CLK) * 16.0 * 10.0 ** (-3))) - 1; -- Every 16 ms
|
||||
signal nlp_timeout_cnt : integer range 0 to NLP_TIMEOUT_CNT_MAX;
|
||||
begin
|
||||
-- Synchronize RX input
|
||||
@ -260,7 +260,7 @@ begin
|
||||
-- -------------------------------------------------------------------------
|
||||
|
||||
transmitter : block
|
||||
constant TX_STB_CNT_MAX : integer := F_CLK / (F_ETH * 2) - 1;
|
||||
constant TX_STB_CNT_MAX : integer := integer(round(real(F_CLK) / real((F_ETH * 2)))) - 1;
|
||||
signal tx_stb_cnt : integer range 0 to TX_STB_CNT_MAX;
|
||||
|
||||
type tx_state_t is (IDLE, NLP, TX, IPG);
|
||||
@ -268,7 +268,7 @@ begin
|
||||
signal sr : std_logic_vector(phy_in.tx_data'range);
|
||||
signal bit_stage : std_logic;
|
||||
|
||||
constant BIT_CNT_MAX_NLP : integer := 16000 / 100; -- 16 ms (timebase 100 ns)
|
||||
constant BIT_CNT_MAX_NLP : integer := 16000000 / 100; -- 16 ms (timebase 100 ns)
|
||||
constant BIT_CNT_MAX_IPG : integer := 96;
|
||||
constant BIT_CNT_MAX_DATA : integer := sr'length - 1;
|
||||
signal bit_cnt : integer range 0 to maximum(maximum(BIT_CNT_MAX_NLP, BIT_CNT_MAX_DATA), BIT_CNT_MAX_IPG);
|
||||
@ -314,15 +314,19 @@ begin
|
||||
|
||||
variable tx_stb : std_logic; -- Strobe every 50 ns (20 MHz)
|
||||
|
||||
variable more_data : std_logic; -- tx_data_en low-latched
|
||||
begin
|
||||
if rst then
|
||||
phy_out.tx_data_ack <= '0';
|
||||
tx_stb_cnt <= TX_STB_CNT_MAX;
|
||||
tx_mode <= OFF;
|
||||
tx_state <= IDLE;
|
||||
bit_cnt <= 0;
|
||||
go_idle;
|
||||
|
||||
elsif rising_edge(clk) then
|
||||
phy_out.tx_data_ack <= '0';
|
||||
more_data := more_data and phy_in.tx_data_en; -- Latch a short low-pulse on tx_en
|
||||
|
||||
if tx_stb_cnt = 0 then
|
||||
tx_stb_cnt <= TX_STB_CNT_MAX;
|
||||
@ -344,6 +348,7 @@ begin
|
||||
when IDLE =>
|
||||
if phy_in.tx_data_en then -- New packet to TX
|
||||
transmit_byte;
|
||||
more_data := '1';
|
||||
bit_stage <= '1';
|
||||
tx_stb_cnt <= TX_STB_CNT_MAX; -- resync
|
||||
|
||||
@ -363,7 +368,7 @@ begin
|
||||
if (bit_stage = '1') then
|
||||
sr <= '0' & sr(sr'high downto sr'low + 1);
|
||||
if bit_cnt = 0 then
|
||||
if phy_in.tx_data_en then
|
||||
if more_data then
|
||||
transmit_byte;
|
||||
else
|
||||
transmit_ipg;
|
||||
@ -378,7 +383,7 @@ begin
|
||||
end case;
|
||||
end if;
|
||||
end process tx_main;
|
||||
phy_out.tx_active <= '1' when tx_state /= IDLE else '0';
|
||||
phy_out.tx_active <= '1' when (tx_state /= IDLE and tx_state /= NLP) else '0';
|
||||
|
||||
driver : process(clk, rst) is
|
||||
begin
|
||||
@ -394,8 +399,8 @@ begin
|
||||
tx_p <= '1';
|
||||
tx_n <= '0';
|
||||
when ACTIVE =>
|
||||
tx_p <= sr(sr'low) xor bit_stage;
|
||||
tx_n <= not (sr(sr'low) xor bit_stage);
|
||||
tx_p <= sr(sr'low) xnor bit_stage;
|
||||
tx_n <= not (sr(sr'low) xnor bit_stage);
|
||||
end case;
|
||||
end if;
|
||||
end process driver;
|
||||
|
@ -59,6 +59,7 @@ package trashernet_pkg is
|
||||
rx_mac_data : byte; -- Ethernet data (after Ethertype)
|
||||
rx_mac_valid : std_logic; -- `rx_mac` values (headers + data) are valid
|
||||
tx_mac_data_ack : std_logic; -- The byte on `tx_mac_data` has been latched. Update to next word.
|
||||
tx_active : std_logic; -- Transmission in progress
|
||||
|
||||
rx_mac_crc_ok : std_logic; -- End of packet, CRC OK (strobe independent from other rx_mac fields)
|
||||
rx_mac_crc_error : std_logic; -- End of packet, CRC invalid
|
||||
|
Loading…
Reference in New Issue
Block a user