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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [ethlib/] [eth_axi_mst.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright  Copyright 2015 GNSS Sensor Ltd. All right reserved.
4
--! @author     Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief      AXI Master device implementing DMA access.
6
--! @details    AMBA4 AXI Master interface module dedicated for the eth MAC.
7
------------------------------------------------------------------------------
8
--! Standard library
9
library ieee;
10
use ieee.std_logic_1164.all;
11
library commonlib;
12
use commonlib.types_common.all;
13
--! AMBA system bus specific library.
14
library ambalib;
15
--! AXI4 configuration constants.
16
use ambalib.types_amba4.all;
17
--! Rocket-chip specific library
18
library ethlib;
19
use ethlib.types_eth.all;
20
 
21
entity eth_axi_mst is
22
  port(
23
    rst     : in  std_ulogic;
24
    clk     : in  std_ulogic;
25
    aximi   : in  nasti_master_in_type;
26
    aximo   : out nasti_master_out_type;
27
    tmsti   : in  eth_tx_ahb_in_type;
28
    tmsto   : out eth_tx_ahb_out_type;
29
    rmsti   : in  eth_rx_ahb_in_type;
30
    rmsto   : out eth_rx_ahb_out_type
31
  );
32
end entity;
33
 
34
architecture rtl of eth_axi_mst is
35
  constant STATE_IDLE   : integer := 0;
36
  constant STATE_W      : integer := STATE_IDLE+1;
37
  constant STATE_R_WAIT_RESP   : integer := STATE_W+1;
38
  constant STATE_R_WAIT_NEXT : integer := STATE_R_WAIT_RESP+1;
39
  constant STATE_B      : integer := STATE_R_WAIT_NEXT+1;
40
 
41
  constant Rx : integer := 0;
42
  constant Tx : integer := 1;
43
 
44
  type eth_in_type is record
45
    req     : std_ulogic;
46
    write   : std_ulogic;
47
    addr    : std_logic_vector(31 downto 0);
48
    data    : std_logic_vector(31 downto 0);
49
    burst_bytes : std_logic_vector(10 downto 0);
50
  end record;
51
 
52
  type eth_out_type is record
53
    grant    : std_ulogic;
54
    data     : std_logic_vector(31 downto 0);
55
    ready    : std_ulogic;
56
    error    : std_ulogic;
57
    retry    : std_ulogic;
58
  end record;
59
 
60
  type eth_out_vector is array (0 to 1) of eth_out_type;
61
 
62
  type reg_type is record
63
    state    : integer range 0 to STATE_B;
64
    len      : integer;
65
    x        : integer range 0 to 1;
66
    waddr2   : std_logic;
67
  end record;
68
 
69
  signal r, rin : reg_type;
70
begin
71
  comb : process(rst, r, tmsti, rmsti,  aximi) is
72
  variable v       : reg_type;
73
  variable xmsti : eth_in_type;
74
  variable xmsto : eth_out_vector;
75
  variable vaximo   : nasti_master_out_type;
76
  variable rdata_lsb : std_logic_vector(31 downto 0);
77
  variable wdata_lsb : std_logic_vector(31 downto 0);
78
  begin
79
    v := r;
80
 
81
 
82
    vaximo := nasti_master_out_none;
83
    vaximo.ar_user       := '0';
84
    vaximo.ar_id         := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
85
    vaximo.ar_bits.size  := "010"; -- 4 bytes
86
    vaximo.ar_bits.burst := NASTI_BURST_INCR;
87
    vaximo.aw_user       := '0';
88
    vaximo.aw_id         := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
89
    vaximo.aw_bits.size  := "010"; -- 4 bytes
90
    vaximo.aw_bits.burst := NASTI_BURST_INCR;
91
 
92
    xmsto := (others => ('0', rdata_lsb, '0', '0', '0'));
93
 
94
    if r.x = Rx then
95
      xmsti.req := rmsti.req;
96
      xmsti.write := rmsti.write;
97
      xmsti.addr := rmsti.addr;
98
      xmsti.data := rmsti.data;
99
      xmsti.burst_bytes := rmsti.burst_bytes;
100
    else
101
      xmsti.req := tmsti.req;
102
      xmsti.write := tmsti.write;
103
      xmsti.addr := tmsti.addr;
104
      xmsti.data := tmsti.data;
105
      xmsti.burst_bytes := tmsti.burst_bytes;
106
    end if;
107
 
108
    -- Pre-fix for SPARC byte order.
109
    -- It is better to fix in MAC itselfm but for now it will be here.
110
    wdata_lsb := xmsti.data(7 downto 0) & xmsti.data(15 downto 8)
111
               & xmsti.data(23 downto 16) & xmsti.data(31 downto 24);
112
    rdata_lsb := aximi.r_data(7 downto 0) & aximi.r_data(15 downto 8)
113
               & aximi.r_data(23 downto 16) & aximi.r_data(31 downto 24);
114
 
115
    case r.state is
116
    when STATE_IDLE =>
117
        if rmsti.req = '1' then
118
            v.x := Rx;
119
            vaximo.ar_valid      := not rmsti.write;
120
            vaximo.aw_valid      := rmsti.write;
121
            if rmsti.write = '1' then
122
                vaximo.aw_bits.addr  := rmsti.addr(31 downto 3) & "000";
123
                v.waddr2 := rmsti.addr(2);
124
                v.len  := conv_integer(rmsti.burst_bytes(10 downto 2)) - 1;
125
                vaximo.aw_bits.len := conv_std_logic_vector(v.len, 8);
126
                if aximi.aw_ready = '1' then
127
                    xmsto(Rx).grant := '1';
128
                    v.state := STATE_W;
129
                end if;
130
            else
131
                vaximo.ar_bits.addr  := rmsti.addr;
132
                v.len  := conv_integer(rmsti.burst_bytes(10 downto 2)) - 1;
133
                vaximo.ar_bits.len := conv_std_logic_vector(v.len, 8);
134
                if aximi.ar_ready = '1' then
135
                    xmsto(Rx).grant := '1';
136
                    v.state := STATE_R_WAIT_RESP;
137
                end if;
138
            end if;
139
        elsif tmsti.req = '1' then
140
            v.x := Tx;
141
            vaximo.ar_valid      := not tmsti.write;
142
            vaximo.aw_valid      := tmsti.write;
143
            if tmsti.write = '1' then
144
                vaximo.aw_bits.addr  := tmsti.addr(31 downto 3) & "000";
145
                v.waddr2 := tmsti.addr(2);
146
                v.len  := conv_integer(tmsti.burst_bytes(10 downto 2)) - 1;
147
                vaximo.aw_bits.len := conv_std_logic_vector(v.len, 8);
148
                if aximi.aw_ready = '1' then
149
                    xmsto(Tx).grant := '1';
150
                    v.state := STATE_W;
151
                end if;
152
            else
153
                vaximo.ar_bits.addr  := tmsti.addr;
154
                v.len  := conv_integer(tmsti.burst_bytes(10 downto 2)) - 1;
155
                vaximo.ar_bits.len := conv_std_logic_vector(v.len, 8);
156
                if aximi.ar_ready = '1' then
157
                    xmsto(Tx).grant := '1';
158
                    v.state := STATE_R_WAIT_RESP;
159
                end if;
160
            end if;
161
        end if;
162
 
163
 
164
    when STATE_R_WAIT_RESP =>
165
        vaximo.r_ready := '1';
166
        if aximi.r_valid = '1' then
167
            xmsto(r.x).ready := '1';
168
            if aximi.r_last = '1' then
169
                v.state := STATE_IDLE;
170
            else
171
                if xmsti.req = '1' then
172
                    xmsto(r.x).grant := '1';
173
                else
174
                    v.state := STATE_R_WAIT_NEXT;
175
                end if;
176
            end if;
177
        end if;
178
 
179
    when STATE_R_WAIT_NEXT =>
180
        if xmsti.req = '1' then
181
            xmsto(r.x).grant := '1';
182
            v.state := STATE_R_WAIT_RESP;
183
        end if;
184
 
185
    when STATE_W =>
186
        vaximo.w_valid := '1';
187
        case r.waddr2 is
188
        when '0' => vaximo.w_strb := X"0f";
189
        when '1' => vaximo.w_strb := X"f0";
190
        when others =>
191
        end case;
192
        vaximo.w_data := wdata_lsb & wdata_lsb;
193
 
194
        if aximi.w_ready = '1' then
195
            xmsto(r.x).ready := '1';
196
            if r.len = 0 then
197
                v.state := STATE_B;
198
                vaximo.w_last := '1';
199
            else
200
                xmsto(r.x).grant := '1';
201
                v.len := r.len - 1;
202
                -- Address will be incremented on slave side
203
                --v.waddr2 := not r.waddr2;
204
            end if;
205
        end if;
206
 
207
    when STATE_B =>
208
        vaximo.w_last := '0';
209
        vaximo.b_ready := '1';
210
        if aximi.b_valid = '1' then
211
            v.state := STATE_IDLE;
212
        end if;
213
    when others =>
214
    end case;
215
 
216
    if rst = '0' then
217
      v.state := STATE_IDLE;
218
      v.waddr2 := '0';
219
      v.len := 0;
220
      v.x := Rx;
221
    end if;
222
 
223
 
224
    rin <= v;
225
    aximo <= vaximo;
226
 
227
    tmsto.grant   <= xmsto(Tx).grant;
228
    tmsto.data    <= xmsto(Tx).data;
229
    tmsto.ready   <= xmsto(Tx).ready;
230
    tmsto.error   <= xmsto(Tx).error;
231
    tmsto.retry   <= xmsto(Tx).retry;
232
 
233
    rmsto.grant   <= xmsto(Rx).grant;
234
    rmsto.data    <= xmsto(Rx).data;
235
    rmsto.ready   <= xmsto(Rx).ready;
236
    rmsto.error   <= xmsto(Rx).error;
237
    rmsto.retry   <= xmsto(Rx).retry;
238
  end process;
239
 
240
  regs : process(clk)
241
  begin
242
    if rising_edge(clk) then r <= rin; end if;
243
  end process;
244
 
245
end architecture;
246
 

powered by: WebSVN 2.1.0

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