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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [dsu/] [axi_dsu.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     Debug Support Unit (DSU) with AXI4 interface.
6
--! @details   DSU provides access to the internal CPU registers via
7
--!            'Debug port' bus interface available only on <b>RIVER</b> CPU.
8
--!            It is also implements a set of registers collecting bus
9
--!            utilization statistic and additional debug information.
10
-----------------------------------------------------------------------------
11
 
12
--! VHDL base library.
13
library ieee;
14
--! VHDL base types import
15
use ieee.std_logic_1164.all;
16
--! VHDL base numeric import
17
use ieee.numeric_std.all;
18
--! SoC common functionality library.
19
library commonlib;
20
--! SoC common types import
21
use commonlib.types_common.all;
22
--! AMBA system bus specific library.
23
library ambalib;
24
--! AXI4 configuration constants.
25
use ambalib.types_amba4.all;
26
--! RIVER CPU specific library.
27
library riverlib;
28
--! RIVER CPU configuration constants.
29
use riverlib.river_cfg.all;
30
--! River top level with AMBA interface module declaration
31
use riverlib.types_river.all;
32
 
33
entity axi_dsu is
34
  generic (
35
    xaddr    : integer := 0;
36
    xmask    : integer := 16#fffff#
37
  );
38
  port
39
  (
40
    clk    : in std_logic;
41
    nrst   : in std_logic;
42
    o_cfg  : out nasti_slave_config_type;
43
    i_axi  : in nasti_slave_in_type;
44
    o_axi  : out nasti_slave_out_type;
45
    o_dporti : out dport_in_type;
46
    i_dporto : in dport_out_type;
47
    --! reset CPU and interrupt controller
48
    o_soft_rst : out std_logic;
49
    -- Platfrom run-time statistic
50
    i_miss_irq  : in std_logic;
51
    i_miss_addr : in std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
52
    i_bus_util_w : in std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0);
53
    i_bus_util_r : in std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0)
54
  );
55
end;
56
 
57
architecture arch_axi_dsu of axi_dsu is
58
 
59
  constant xconfig : nasti_slave_config_type := (
60
     descrtype => PNP_CFG_TYPE_SLAVE,
61
     descrsize => PNP_CFG_SLAVE_DESCR_BYTES,
62
     irq_idx => 0,
63
     xaddr => conv_std_logic_vector(xaddr, CFG_NASTI_CFG_ADDR_BITS),
64
     xmask => conv_std_logic_vector(xmask, CFG_NASTI_CFG_ADDR_BITS),
65
     vid => VENDOR_GNSSSENSOR,
66
     did => GNSSSENSOR_DSU
67
  );
68
 
69
type state_type is (reading, writting, dport_response, ready);
70
 
71
type mst_utilization_type is array (0 to CFG_NASTI_MASTER_TOTAL-1)
72
       of std_logic_vector(63 downto 0);
73
 
74
type mst_utilization_map_type is array (0 to 2*CFG_NASTI_MASTER_TOTAL-1)
75
       of std_logic_vector(63 downto 0);
76
 
77
type registers is record
78
  bank_axi : nasti_slave_bank_type;
79
  --! Message multiplexer to form 32->64 request message
80
  state         : state_type;
81
  waddr : std_logic_vector(13 downto 0);
82
  wdata : std_logic_vector(63 downto 0);
83
  rdata : std_logic_vector(63 downto 0);
84
  soft_rst : std_logic;
85
  -- Platform statistic:
86
  clk_cnt : std_logic_vector(63 downto 0);
87
  miss_access_cnt : std_logic_vector(63 downto 0);
88
  miss_access_addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
89
  util_w_cnt : mst_utilization_type;
90
  util_r_cnt : mst_utilization_type;
91
end record;
92
 
93
signal r, rin: registers;
94
begin
95
 
96
  comblogic : process(nrst, i_axi, i_dporto, i_miss_irq, i_miss_addr,
97
                      i_bus_util_w, i_bus_util_r, r)
98
    variable v : registers;
99
    variable mux_rdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
100
    variable vdporti : dport_in_type;
101
    variable iraddr : integer;
102
    variable wb_bus_util_map : mst_utilization_map_type;
103
  begin
104
    v := r;
105
    v.rdata := (others => '0');
106
    vdporti.valid := '0';
107
    vdporti.write := '0';
108
    vdporti.region := (others => '0');
109
    vdporti.addr := (others => '0');
110
    vdporti.wdata := (others => '0');
111
 
112
    -- Update statistic:
113
    v.clk_cnt := r.clk_cnt + 1;
114
    if i_miss_irq = '1' then
115
      v.miss_access_addr := i_miss_addr;
116
      v.miss_access_cnt := r.miss_access_cnt + 1;
117
    end if;
118
 
119
    for n in 0 to CFG_NASTI_MASTER_TOTAL-1 loop
120
       if i_bus_util_w(n) = '1' then
121
         v.util_w_cnt(n) := r.util_w_cnt(n) + 1;
122
       end if;
123
       if i_bus_util_r(n) = '1' then
124
         v.util_r_cnt(n) := r.util_r_cnt(n) + 1;
125
       end if;
126
    end loop;
127
 
128
    for n in 0 to CFG_NASTI_MASTER_TOTAL-1 loop
129
      wb_bus_util_map(2*n) := r.util_w_cnt(n);
130
      wb_bus_util_map(2*n+1) := r.util_r_cnt(n);
131
    end loop;
132
 
133
    procedureAxi4(i_axi, xconfig, r.bank_axi, v.bank_axi);
134
    --! redefine value 'always ready' inserting waiting states.
135
    v.bank_axi.rwaitready := '0';
136
 
137
    if r.bank_axi.wstate = wtrans then
138
      -- 32-bits burst transaction
139
      v.waddr := r.bank_axi.waddr(0)(16 downto 3);
140
      if r.bank_axi.wburst = NASTI_BURST_INCR and r.bank_axi.wsize = 4 then
141
         if r.bank_axi.waddr(0)(2) = '1' then
142
             v.state := writting;
143
             v.wdata(63 downto 32) := i_axi.w_data(31 downto 0);
144
         else
145
             v.wdata(31 downto 0) := i_axi.w_data(31 downto 0);
146
         end if;
147
      else
148
         -- Write data on next clock.
149
         if i_axi.w_strb /= X"00" then
150
            v.wdata := i_axi.w_data;
151
         end if;
152
         v.state := writting;
153
      end if;
154
    end if;
155
 
156
    case r.state is
157
      when reading =>
158
           if r.bank_axi.rstate = rtrans then
159
              if r.bank_axi.raddr(0)(16 downto 15) = "11" then
160
                --! local region
161
                v.bank_axi.rwaitready := '1';
162
                iraddr := conv_integer(r.bank_axi.raddr(0)(14 downto 3));
163
                case iraddr is
164
                when 0 =>
165
                  v.rdata(0) := r.soft_rst;
166
                when 1 =>
167
                  v.rdata := r.miss_access_cnt;
168
                when 2 =>
169
                  v.rdata(CFG_NASTI_ADDR_BITS-1 downto 0) := r.miss_access_addr;
170
                when others =>
171
                  if (iraddr >= 8) and (iraddr < (8 + 2*CFG_NASTI_MASTER_TOTAL)) then
172
                      v.rdata := wb_bus_util_map(iraddr - 8);
173
                  end if;
174
                end case;
175
                v.state := ready;
176
              else
177
                --! debug port regions: 0 to 2
178
                vdporti.valid := '1';
179
                vdporti.write := '0';
180
                vdporti.region := r.bank_axi.raddr(0)(16 downto 15);
181
                vdporti.addr := r.bank_axi.raddr(0)(14 downto 3);
182
                vdporti.wdata := (others => '0');
183
                v.state := dport_response;
184
              end if;
185
           end if;
186
      when writting =>
187
           v.state := reading;
188
           if r.waddr(13 downto 12) = "11" then
189
             --! local region
190
             case conv_integer(r.waddr(11 downto 0)) is
191
             when 0 =>
192
               v.soft_rst := r.wdata(0);
193
             when others =>
194
             end case;
195
           else
196
             --! debug port regions: 0 to 2
197
             vdporti.valid := '1';
198
             vdporti.write := '1';
199
             vdporti.region := r.waddr(13 downto 12);
200
             vdporti.addr := r.waddr(11 downto 0);
201
             vdporti.wdata := r.wdata;
202
           end if;
203
      when dport_response =>
204
             v.state := ready;
205
             v.bank_axi.rwaitready := '1';
206
             v.rdata := i_dporto.rdata;
207
      when ready =>
208
             v.state := reading;
209
      when others =>
210
    end case;
211
 
212
    if r.bank_axi.raddr(0)(2) = '0' then
213
       mux_rdata(31 downto 0) := r.rdata(31 downto 0);
214
    else
215
       -- 32-bits aligned access (can be generated by MAC)
216
       mux_rdata(31 downto 0) := r.rdata(63 downto 32);
217
    end if;
218
    mux_rdata(63 downto 32) := r.rdata(63 downto 32);
219
 
220
    o_axi <= functionAxi4Output(r.bank_axi, mux_rdata);
221
 
222
    if nrst = '0' then
223
       v.bank_axi := NASTI_SLAVE_BANK_RESET;
224
       v.state := reading;
225
       v.waddr := (others => '0');
226
       v.wdata := (others => '0');
227
       v.rdata := (others => '0');
228
       v.soft_rst := '0';
229
       v.clk_cnt := (others => '0');
230
       v.miss_access_cnt := (others => '0');
231
       v.miss_access_addr := (others => '0');
232
       v.util_w_cnt := (others => (others => '0'));
233
       v.util_r_cnt := (others => (others => '0'));
234
    end if;
235
 
236
    rin <= v;
237
 
238
    o_dporti <= vdporti;
239
  end process;
240
 
241
  o_cfg  <= xconfig;
242
  o_soft_rst <= r.soft_rst;
243
 
244
 
245
  -- registers:
246
  regs : process(clk)
247
  begin
248
    if rising_edge(clk) then
249
       r <= rin;
250
    end if;
251
  end process;
252
end;

powered by: WebSVN 2.1.0

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