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

Subversion Repositories etherlab

[/] [etherlab/] [trunk/] [vhdl/] [mac_snd.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 idiolatrie
--------------------------------------------------------------------------------
2
-- ETHERLAB - FPGA To C# To LABVIEW Bridge                                    --
3
--------------------------------------------------------------------------------
4
-- REFERENCES                                                                 --
5
--  [1] http://tools.ietf.org/html/rfc2460                                    --
6
--  [2] https://en.wikipedia.org/wiki/Ethernet_frame                          --
7
--  [5] http://outputlogic.com/my-stuff/circuit-cellar-january-2010-crc.pdf   --
8
--  [6] OPB Ethernet Lite Media Access Controller (v1.01b)                    --
9
--  [7] LAN83C185 - 10/100 Ethernet PHY                                       --
10
--  [8] Xilinx UG230                                                          --
11
--------------------------------------------------------------------------------
12
-- Copyright (C)2012  Mathias Hörtnagl <mathias.hoertnagl@gmail.com>          --
13
--                                                                            --
14
-- This program is free software: you can redistribute it and/or modify       --
15
-- it under the terms of the GNU General Public License as published by       --
16
-- the Free Software Foundation, either version 3 of the License, or          --
17
-- (at your option) any later version.                                        --
18
--                                                                            --
19
-- This program is distributed in the hope that it will be useful,            --
20
-- but WITHOUT ANY WARRANTY; without even the implied warranty of             --
21
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              --
22
-- GNU General Public License for more details.                               --
23
--                                                                            --
24
-- You should have received a copy of the GNU General Public License          --
25
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.      --
26
--------------------------------------------------------------------------------
27
library ieee;
28
use ieee.std_logic_1164.all;
29
use ieee.numeric_std.all;
30
 
31
library work;
32
use work.PCK_CRC32_D4.all;
33
use work.common.all;
34
 
35
entity mac_snd is
36
   port(
37
      E_TX_CLK : in  std_logic;                       -- Sender Clock.
38
      E_TX_EN  : out std_logic;                       -- Sender Enable.
39
      E_TXD    : out std_logic_vector(3 downto 0);    -- Sent Data.
40
      E_TX_ER  : out std_logic;                       -- Sent Data Error.
41
      el_chnl  : in  std_logic_vector(7 downto 0);    -- EtherLab channels.
42
      el_data  : in  data_t;                          -- EtherLab data.
43
      en       : in  std_logic                        -- User Start Send. 
44
   );
45
end mac_snd;
46
 
47
architecture rtl of mac_snd is
48
 
49
   type mem_t is array(0 to 14) of std_logic_vector(7 downto 0);
50
 
51
   signal mem : mem_t := (
52
      --------------------------------------------------------------------------
53
      -- Host PC MAC Address                                                  --
54
      --------------------------------------------------------------------------
55
      -- 0x0 - 0x5
56
      x"00", x"1f", x"16", x"01", x"95", x"5a",
57
 
58
      --------------------------------------------------------------------------
59
      -- FPGA MAC Address (Xilinx OUI)                                        --
60
      --------------------------------------------------------------------------
61
      -- 0x6 - 0xb
62
      x"00", x"0a", x"35", x"00", x"00", x"00",
63
 
64
      --------------------------------------------------------------------------
65
      -- EtherType Field: 0x0000 (EtherLab)                                   --
66
      --------------------------------------------------------------------------
67
      -- 0xc - 0xd
68
      x"00", x"00",
69
 
70
      --------------------------------------------------------------------------
71
      -- EtherLab Header                                                      --
72
      --------------------------------------------------------------------------
73
      -- EtherLab Version. 
74
      -- Hardware returns Version 2 packets to distinguish them from Version 1 
75
      -- packets sent by the host who captures in promiscuous mode only. This
76
      -- would cause the host to read it's own Version 1 packets as well.
77
      -- 0xe
78
      x"02"
79
   );
80
 
81
   attribute RAM_STYLE : string;
82
   attribute RAM_STYLE of mem: signal is "BLOCK";
83
 
84
   type state_t is (
85
      Idle,                      -- Wait for signal en.
86
      Preamble,                  -- 55 55 55 55 55 55 55 5
87
      StartOfFrame,              -- d
88
      Upper,                     -- Send upper Nibble.
89
      Lower,                     -- Send lower Nibble.
90
      Channel,                   -- Send EtherLab channel.
91
      DataU, DataL,              -- Send EtherLab data.
92
      FrameCheck,                -- No Frame Check for now.
93
      InterframeGap              -- Gap between two cosecutive frames (93 Bit).
94
   );
95
 
96
   type snd_t is record
97
      s   : state_t;
98
      crc : std_logic_vector(31 downto 0);   -- CRC32 latch.
99
      c   : natural range 0 to 63;
100
      a   : natural range 0 to 7;
101
   end record;
102
 
103
   signal s, sin : snd_t := snd_t'(Idle, x"ffffffff", 0, 0);
104
begin
105
 
106
   snd_nsl : process(s, mem, en, el_chnl, el_data)
107
   begin
108
 
109
      sin     <= s;
110
      E_TX_EN <= '0';
111
      E_TXD   <= x"0";
112
      E_TX_ER <= '0';
113
 
114
      case s.s is
115
         when Idle =>
116
            if en = '1' then
117
               sin.c <= 0;
118
               sin.s <= Preamble;
119
            end if;
120
 
121
         -----------------------------------------------------------------------
122
         -- Ethernet II - Preamble and Start Of Frame.                        --
123
         -----------------------------------------------------------------------            
124
         when Preamble =>
125
            E_TXD   <= x"5";
126
            E_TX_EN <= '1';
127
            if s.c = 14 then
128
               sin.c <= 0;
129
               sin.s <= StartOfFrame;
130
            else
131
               sin.c <= s.c + 1;
132
            end if;
133
 
134
         when StartOfFrame =>
135
            E_TXD   <= x"d";
136
            E_TX_EN <= '1';
137
            sin.crc <= x"ffffffff";
138
            sin.s   <= Upper;
139
 
140
         -----------------------------------------------------------------------
141
         -- Custom Protocol Transmit.                                         --
142
         -----------------------------------------------------------------------            
143
         when Upper =>
144
            E_TXD   <= mem(s.c)(3 downto 0);
145
            E_TX_EN <= '1';
146
            sin.crc <= nextCRC32_D4(mem(s.c)(3 downto 0), s.crc);
147
            sin.s   <= Lower;
148
 
149
         when Lower =>
150
            E_TXD   <= mem(s.c)(7 downto 4);
151
            E_TX_EN <= '1';
152
            sin.crc <= nextCRC32_D4(mem(s.c)(7 downto 4), s.crc);
153
            if s.c = 14 then
154
               sin.c <= 0;
155
               sin.s <= Channel;
156
            else
157
               sin.c <= s.c + 1;
158
               sin.s <= Upper;
159
            end if;
160
 
161
         -----------------------------------------------------------------------
162
         -- EtherLab - Channel Flags.                                         --
163
         -----------------------------------------------------------------------
164
         when Channel =>
165
            E_TXD   <= el_chnl(4*s.c+3 downto 4*s.c);
166
            E_TX_EN <= '1';
167
            sin.crc <= nextCRC32_D4(el_chnl(4*s.c+3 downto 4*s.c), s.crc);
168
            if s.c = 1 then
169
               sin.c <= 0;
170
               sin.a <= 0;
171
               sin.s <= DataU;
172
            else
173
               sin.c <= s.c + 1;
174
            end if;
175
 
176
         -----------------------------------------------------------------------
177
         -- EtherLab - Data. 8 channels á 16 bit.                             --
178
         -----------------------------------------------------------------------
179
         when DataU =>
180
            E_TXD   <= el_data(s.a)(4*s.c+11 downto 4*s.c+8);
181
            E_TX_EN <= '1';
182
            sin.crc <= nextCRC32_D4(el_data(s.a)(4*s.c+11 downto 4*s.c+8), s.crc);
183
            if s.c = 1 then
184
               sin.c <= 0;
185
               sin.s <= DataL;
186
            else
187
               sin.c <= s.c + 1;
188
            end if;
189
 
190
         when DataL =>
191
            E_TXD   <= el_data(s.a)(4*s.c+3 downto 4*s.c);
192
            E_TX_EN <= '1';
193
            sin.crc <= nextCRC32_D4(el_data(s.a)(4*s.c+3 downto 4*s.c), s.crc);
194
            if s.c = 1 then
195
               sin.c <= 0;
196
               if s.a = 7 then
197
                  sin.a <= 0;
198
                  sin.s <= FrameCheck;
199
               else
200
                  sin.a <= s.a + 1;
201
                  sin.s <= DataU;
202
               end if;
203
            else
204
               sin.c <= s.c + 1;
205
            end if;
206
 
207
         -----------------------------------------------------------------------
208
         -- Ethernet II - Frame Check.                                        --
209
         -----------------------------------------------------------------------            
210
         when FrameCheck =>
211
            E_TXD   <= not s.crc(4*s.c+3 downto 4*s.c);
212
            E_TX_EN <= '1';
213
            if s.c = 7 then
214
               sin.c <= 0;
215
               sin.s <= InterframeGap;
216
            else
217
               sin.c <= s.c + 1;
218
            end if;
219
 
220
         -----------------------------------------------------------------------
221
         -- Ethernet II - Interframe Gap.                                     --
222
         -----------------------------------------------------------------------            
223
         when InterframeGap =>
224
            if s.c = 23 then
225
               sin.c <= 0;
226
               sin.s <= Idle;
227
            else
228
               sin.c <= s.c + 1;
229
            end if;
230
      end case;
231
   end process;
232
 
233
   snd_reg : process(E_TX_CLK)
234
   begin
235
      if rising_edge(E_TX_CLK) then
236
         s <= sin;
237
      end if;
238
   end process;
239
end rtl;

powered by: WebSVN 2.1.0

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