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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [vhdl/] [eth_dma.vhd] - Blame information for rev 288

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 288 rhoads
---------------------------------------------------------------------
2
-- TITLE: Ethernet DMA
3
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
-- DATE CREATED: 12/27/07
5
-- FILENAME: eth_dma.vhd
6
-- PROJECT: Plasma CPU core
7
-- COPYRIGHT: Software placed into the public domain by the author.
8
--    Software 'as is' without warranty.  Author liable for nothing.
9
-- DESCRIPTION:
10
--    Ethernet DMA (Direct Memory Access) controller.  
11
--    Reads four bits and writes four bits from/to the Ethernet PHY each 
12
--    2.5 MHz clock cycle.  Received data is DMAed starting at 0x13ff0000 
13
--    transmit data is read from 0x13fd0000.
14
--    To send a packet write bytes/4 to Ethernet send register.
15
---------------------------------------------------------------------
16
library ieee;
17
use ieee.std_logic_1164.all;
18
use ieee.std_logic_unsigned.all;
19
use ieee.std_logic_arith.all;
20
use work.mlite_pack.all;
21
 
22
entity eth_dma is port(
23
   clk         : in std_logic;                      --25 MHz
24
   reset       : in std_logic;
25
   enable_eth  : in std_logic;                      --enable receive DMA
26
   select_eth  : in std_logic;
27
   rec_isr     : out std_logic;                     --data received
28
   send_isr    : out std_logic;                     --transmit done
29
 
30
   address     : out std_logic_vector(31 downto 2); --to DDR
31
   byte_we     : out std_logic_vector(3 downto 0);
32
   data_write  : out std_logic_vector(31 downto 0);
33
   data_read   : in std_logic_vector(31 downto 0);
34
   pause_in    : in std_logic;
35
 
36
   mem_address : in std_logic_vector(31 downto 2);  --from CPU
37
   mem_byte_we : in std_logic_vector(3 downto 0);
38
   data_w      : in std_logic_vector(31 downto 0);
39
   pause_out   : out std_logic;
40
 
41
   E_RX_CLK    : in std_logic;                      --2.5 MHz receive
42
   E_RX_DV     : in std_logic;                      --data valid
43
   E_RXD       : in std_logic_vector(3 downto 0);   --receive nibble
44
   E_TX_CLK    : in std_logic;                      --2.5 MHz transmit
45
   E_TX_EN     : out std_logic;                     --transmit enable
46
   E_TXD       : out std_logic_vector(3 downto 0)); --transmit nibble
47
end; --entity eth_dma
48
 
49
architecture logic of eth_dma is
50
   signal rec_clk    : std_logic_vector(1 downto 0);  --receive
51
   signal rec_valid  : std_logic;
52
   signal rec_latch  : std_logic_vector(3 downto 0);
53
   signal rec_store  : std_logic_vector(31 downto 0); --to DDR
54
   signal rec_data   : std_logic_vector(27 downto 0);
55
   signal rec_cnt    : std_logic_vector(2 downto 0);  --nibbles
56
   signal rec_words  : std_logic_vector(13 downto 0);
57
   signal rec_dma    : std_logic_vector(1 downto 0);  --active & request
58
   signal rec_done   : std_logic;
59
 
60
   signal send_clk   : std_logic_vector(1 downto 0);  --transmit
61
   signal send_read  : std_logic_vector(31 downto 0); --from DDR
62
   signal send_data  : std_logic_vector(31 downto 0);
63
   signal send_cnt   : std_logic_vector(2 downto 0);  --nibbles
64
   signal send_words : std_logic_vector(8 downto 0);
65
   signal send_level : std_logic_vector(8 downto 0);
66
   signal send_dma   : std_logic_vector(1 downto 0);  --active & request
67
   signal send_enable: std_logic;
68
 
69
begin  --architecture
70
 
71
   dma_proc: process(clk, reset, enable_eth, select_eth,
72
         data_read, pause_in, mem_address, mem_byte_we, data_w,
73
         E_RX_CLK, E_RX_DV, E_RXD, E_TX_CLK,
74
         rec_clk, rec_valid, rec_latch, rec_store, rec_data,
75
         rec_cnt, rec_words, rec_dma, rec_done,
76
         send_clk, send_read, send_data, send_cnt, send_words,
77
         send_level, send_dma, send_enable)
78
   begin
79
 
80
      if rising_edge(E_RX_CLK) then
81
         rec_valid <= E_RX_DV;
82
         rec_latch <= E_RXD;
83
      end if;
84
 
85
      if reset = '1' then
86
         rec_clk <= "00";
87
         rec_cnt <= "000";
88
         rec_words <= ZERO(13 downto 0);
89
         rec_dma <= "00";
90
         rec_done <= '0';
91
         send_clk <= "00";
92
         send_cnt <= "000";
93
         send_words <= ZERO(8 downto 0);
94
         send_level <= ZERO(8 downto 0);
95
         send_dma <= "00";
96
         send_enable <= '0';
97
      elsif rising_edge(clk) then
98
 
99
         --Receive nibble on low->high E_RX_CLK.  Send to DDR every 32 bits.
100
         rec_clk <= rec_clk(0) & E_RX_CLK;
101
         if rec_clk = "01" and enable_eth = '1' then
102
            if rec_valid = '1' or rec_cnt /= "000" then
103
               if rec_cnt = "111" then
104
                  rec_store <= rec_data & rec_latch;
105
                  rec_dma(0) <= '1';           --request DMA
106
               end if;
107
               rec_data <= rec_data(23 downto 0) & rec_latch;
108
               rec_cnt <= rec_cnt + 1;
109
            end if;
110
         end if;
111
 
112
         --Set transmit count or clear receive interrupt
113
         if select_eth = '1' then
114
            if mem_byte_we /= "0000" then
115
               send_cnt <= "000";
116
               send_words <= ZERO(8 downto 0);
117
               send_level <= data_w(8 downto 0);
118
               send_dma(0) <= '1';
119
            else
120
               rec_done <= '0';
121
            end if;
122
         end if;
123
 
124
         --Transmit nibble on low->high E_TX_CLK.  Get 32 bits from DDR.
125
         send_clk <= send_clk(0) & E_TX_CLK;
126
         if send_clk = "01" then
127
            if send_cnt = "111" then
128
               if send_words /= send_level then
129
                  send_data <= send_read;
130
                  send_dma(0) <= '1';
131
                  send_enable <= '1';
132
               else
133
                  send_enable <= '0';
134
               end if;
135
            else
136
               send_data(31 downto 4) <= send_data(27 downto 0);
137
            end if;
138
            send_cnt <= send_cnt + 1;
139
         end if;
140
 
141
         --Pick which type of DMA operation: bit0 = request; bit1 = active
142
         if pause_in = '0' then
143
            if rec_dma(1) = '1' then
144
               rec_dma <= "00";               --DMA done
145
               rec_words <= rec_words + 1;
146
               if rec_valid = '0' then
147
                  rec_done <= '1';
148
               end if;
149
            elsif send_dma(1) = '1' then
150
               send_dma <= "00";
151
               send_words <= send_words + 1;
152
               send_read <= data_read;
153
            elsif rec_dma(0) = '1' then
154
               rec_dma(1) <= '1';             --start DMA
155
            elsif send_dma(0) = '1' then
156
               send_dma(1) <= '1';            --start DMA
157
            end if;
158
         end if;
159
 
160
      end if;  --rising_edge(clk)
161
 
162
      E_TXD <= send_data(31 downto 28);
163
      E_TX_EN <= send_enable;
164
      rec_isr <= rec_done;
165
      if send_words = send_level then
166
         send_isr <= '1';
167
      else
168
         send_isr <= '0';
169
      end if;
170
 
171
      if rec_dma(1) = '1' then
172
         address <= "0001001111111111" & rec_words;        --0x13ff0000
173
         byte_we <= "1111";
174
         data_write <= rec_store;
175
         pause_out <= '1';                                 --to CPU
176
      elsif send_dma(1) = '1' then
177
         address <= "000100111111111000000" & send_words;  --0x13fe0000
178
         byte_we <= "0000";
179
         data_write <= data_w;
180
         pause_out <= '1';
181
      else
182
         address <= mem_address;  --Send request from CPU to DDR
183
         byte_we <= mem_byte_we;
184
         data_write <= data_w;
185
         pause_out <= '0';
186
      end if;
187
 
188
   end process;
189
 
190
end; --architecture logic

powered by: WebSVN 2.1.0

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