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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_debug_dm.vhd] - Blame information for rev 73

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 59 zero_gravi
-- #################################################################################################
2
-- # << NEORV32 - RISC-V-Compatible Debug Module (DM) >>                                           #
3
-- # ********************************************************************************************* #
4
-- # Compatible to the "Minimal RISC-V External Debug Spec. Version 0.13.2"                        #
5
-- # -> "Execution-based" debugging scheme                                                         # 
6
-- # ********************************************************************************************* #
7
-- # Key features:                                                                                 #
8
-- # * register access commands only                                                               #
9
-- # * auto-execution commands                                                                     #
10
-- # * for a single hart only                                                                      #
11
-- # * 2 general purpose program buffer entries                                                    #
12
-- # * 1 general purpose data buffer entry                                                         #
13
-- #                                                                                               #
14
-- # CPU access:                                                                                   #
15
-- # * ROM for "park loop" code                                                                    #
16
-- # * program buffer                                                                              #
17
-- # * data buffer                                                                                 #
18
-- # * control and status register                                                                 #
19
-- # ********************************************************************************************* #
20
-- # BSD 3-Clause License                                                                          #
21
-- #                                                                                               #
22 71 zero_gravi
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
23 59 zero_gravi
-- #                                                                                               #
24
-- # Redistribution and use in source and binary forms, with or without modification, are          #
25
-- # permitted provided that the following conditions are met:                                     #
26
-- #                                                                                               #
27
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
28
-- #    conditions and the following disclaimer.                                                   #
29
-- #                                                                                               #
30
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
31
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
32
-- #    provided with the distribution.                                                            #
33
-- #                                                                                               #
34
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
35
-- #    endorse or promote products derived from this software without specific prior written      #
36
-- #    permission.                                                                                #
37
-- #                                                                                               #
38
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
39
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
40
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
41
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
42
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
43
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
44
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
45
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
46
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
47
-- # ********************************************************************************************* #
48
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
49
-- #################################################################################################
50
 
51
library ieee;
52
use ieee.std_logic_1164.all;
53
use ieee.numeric_std.all;
54
 
55
library neorv32;
56
use neorv32.neorv32_package.all;
57
 
58
entity neorv32_debug_dm is
59
  port (
60
    -- global control --
61
    clk_i            : in  std_ulogic; -- global clock line
62
    rstn_i           : in  std_ulogic; -- global reset line, low-active
63
    -- debug module interface (DMI) --
64
    dmi_rstn_i       : in  std_ulogic;
65
    dmi_req_valid_i  : in  std_ulogic;
66
    dmi_req_ready_o  : out std_ulogic; -- DMI is allowed to make new requests when set
67
    dmi_req_addr_i   : in  std_ulogic_vector(06 downto 0);
68
    dmi_req_op_i     : in  std_ulogic; -- 0=read, 1=write
69
    dmi_req_data_i   : in  std_ulogic_vector(31 downto 0);
70
    dmi_resp_valid_o : out std_ulogic; -- response valid when set
71
    dmi_resp_ready_i : in  std_ulogic; -- ready to receive respond
72
    dmi_resp_data_o  : out std_ulogic_vector(31 downto 0);
73
    dmi_resp_err_o   : out std_ulogic; -- 0=ok, 1=error
74
    -- CPU bus access --
75 71 zero_gravi
    cpu_debug_i      : in  std_ulogic; -- CPU is in debug mode
76 59 zero_gravi
    cpu_addr_i       : in  std_ulogic_vector(31 downto 0); -- address
77
    cpu_rden_i       : in  std_ulogic; -- read enable
78
    cpu_wren_i       : in  std_ulogic; -- write enable
79
    cpu_data_i       : in  std_ulogic_vector(31 downto 0); -- data in
80
    cpu_data_o       : out std_ulogic_vector(31 downto 0); -- data out
81
    cpu_ack_o        : out std_ulogic; -- transfer acknowledge
82
    -- CPU control --
83
    cpu_ndmrstn_o    : out std_ulogic; -- soc reset
84
    cpu_halt_req_o   : out std_ulogic  -- request hart to halt (enter debug mode)
85
  );
86
end neorv32_debug_dm;
87
 
88
architecture neorv32_debug_dm_rtl of neorv32_debug_dm is
89
 
90
  -- DM configuration --
91
  constant nscratch_c   : std_ulogic_vector(03 downto 0) := "0001"; -- number of dscratch* registers in CPU = 1
92
  constant dataaccess_c : std_ulogic                     := '1';    -- 1: abstract data is memory-mapped, 0: abstract data is CSR-mapped
93
  constant datasize_c   : std_ulogic_vector(03 downto 0) := "0001"; -- number of data registers in memory/CSR space = 1
94
  constant dataaddr_c   : std_ulogic_vector(11 downto 0) := dm_data_base_c(11 downto 0); -- signed base address of data registers in memory/CSR space
95
 
96
  -- available DMI registers --
97
  constant addr_data0_c        : std_ulogic_vector(6 downto 0) := "000" & x"4";
98
  constant addr_dmcontrol_c    : std_ulogic_vector(6 downto 0) := "001" & x"0";
99
  constant addr_dmstatus_c     : std_ulogic_vector(6 downto 0) := "001" & x"1";
100
  constant addr_hartinfo_c     : std_ulogic_vector(6 downto 0) := "001" & x"2";
101
  constant addr_abstractcs_c   : std_ulogic_vector(6 downto 0) := "001" & x"6";
102
  constant addr_command_c      : std_ulogic_vector(6 downto 0) := "001" & x"7";
103
  constant addr_abstractauto_c : std_ulogic_vector(6 downto 0) := "001" & x"8";
104
  constant addr_nextdm_c       : std_ulogic_vector(6 downto 0) := "001" & x"d";
105
  constant addr_progbuf0_c     : std_ulogic_vector(6 downto 0) := "010" & x"0";
106
  constant addr_progbuf1_c     : std_ulogic_vector(6 downto 0) := "010" & x"1";
107
  constant addr_sbcs_c         : std_ulogic_vector(6 downto 0) := "011" & x"8";
108
  constant addr_haltsum0_c     : std_ulogic_vector(6 downto 0) := "100" & x"0";
109
 
110
  -- RISC-V 32-bit instruction prototypes --
111
  constant instr_nop_c    : std_ulogic_vector(31 downto 0) := x"00000013"; -- nop
112
  constant instr_lw_c     : std_ulogic_vector(31 downto 0) := x"00002003"; -- lw zero, 0(zero)
113
  constant instr_sw_c     : std_ulogic_vector(31 downto 0) := x"00002023"; -- sw zero, 0(zero)
114
  constant instr_ebreak_c : std_ulogic_vector(31 downto 0) := x"00100073"; -- ebreak
115
 
116
  -- debug module controller --
117
  type dm_ctrl_state_t is (CMD_IDLE, CMD_EXE_CHECK, CMD_EXE_PREPARE, CMD_EXE_TRIGGER, CMD_EXE_BUSY, CMD_EXE_ERROR);
118
  type dm_ctrl_t is record
119
    -- fsm --
120
    state           : dm_ctrl_state_t;
121
    busy            : std_ulogic;
122
    ldsw_progbuf    : std_ulogic_vector(31 downto 0);
123
    pbuf_en         : std_ulogic;
124
    -- error flags --
125
    illegal_state   : std_ulogic;
126
    illegal_cmd     : std_ulogic;
127
    cmderr          : std_ulogic_vector(02 downto 0);
128
    -- hart status --
129
    hart_halted     : std_ulogic;
130
    hart_resume_req : std_ulogic;
131
    hart_resume_ack : std_ulogic;
132
    hart_reset      : std_ulogic;
133
  end record;
134
  signal dm_ctrl : dm_ctrl_t;
135
 
136
  -- debug module DMI registers / access --
137
  type progbuf_t is array (0 to 1) of std_ulogic_vector(31 downto 0);
138
  type dm_reg_t is record
139
    dmcontrol_ndmreset : std_ulogic;
140
    dmcontrol_dmactive : std_ulogic;
141
    abstractauto_autoexecdata    : std_ulogic;
142
    abstractauto_autoexecprogbuf : std_ulogic_vector(01 downto 0);
143
    progbuf     : progbuf_t;
144
    command     : std_ulogic_vector(31 downto 0);
145
    --
146
    halt_req    : std_ulogic;
147
    resume_req  : std_ulogic;
148
    reset_ack   : std_ulogic;
149
    wr_acc_err  : std_ulogic;
150
    rd_acc_err  : std_ulogic;
151
    clr_acc_err : std_ulogic;
152
    autoexec_wr : std_ulogic;
153
    autoexec_rd : std_ulogic;
154
  end record;
155
  signal dm_reg : dm_reg_t;
156
 
157
  -- cpu program buffer --
158
  type cpu_progbuf_t is array (0 to 4) of std_ulogic_vector(31 downto 0);
159
  signal cpu_progbuf : cpu_progbuf_t;
160
 
161
  -- **********************************************************
162
  -- CPU Bus Interface
163
  -- **********************************************************
164
 
165
  -- Debug Core Interface
166
  type dci_t is record
167
    halt_ack      : std_ulogic; -- CPU (re-)entered HALT state (single-shot)
168
    resume_req    : std_ulogic; -- DM wants the CPU to resume when set
169
    resume_ack    : std_ulogic; -- CPU starts resuming when set (single-shot)
170
    execute_req   : std_ulogic; -- DM wants CPU to execute program buffer when set
171
    execute_ack   : std_ulogic; -- CPU starts executing program buffer when set (single-shot)
172
    exception_ack : std_ulogic; -- CPU has detected an exception (single-shot)
173
    progbuf       : std_ulogic_vector(255 downto 0); -- program buffer, 4 32-bit entries
174
    data_we       : std_ulogic; -- write abstract data
175
    wdata         : std_ulogic_vector(31 downto 0); -- abstract write data
176
    rdata         : std_ulogic_vector(31 downto 0); -- abstract read data
177
  end record;
178
  signal dci : dci_t;
179
 
180
  -- IO space: module base address --
181
  constant hi_abb_c : natural := 31; -- high address boundary bit
182
  constant lo_abb_c : natural := index_size_f(dm_size_c); -- low address boundary bit
183
 
184
  -- status and control register - bits --
185
  constant sreg_halt_ack_c      : natural := 0; -- -/w: CPU is halted in debug mode and waits in park loop
186
  constant sreg_resume_req_c    : natural := 1; -- r/-: DM requests CPU to resume
187
  constant sreg_resume_ack_c    : natural := 2; -- -/w: CPU starts resuming
188
  constant sreg_execute_req_c   : natural := 3; -- r/-: DM requests to execute program buffer
189
  constant sreg_execute_ack_c   : natural := 4; -- -/w: CPU starts to execute program buffer
190
  constant sreg_exception_ack_c : natural := 5; -- -/w: CPU has detected an exception
191
 
192 60 zero_gravi
  -- code ROM containing "park loop" --
193 59 zero_gravi
  type code_rom_file_t is array (0 to 31) of std_ulogic_vector(31 downto 0);
194
  constant code_rom_file : code_rom_file_t := (
195
    00000000 => x"0180006f",
196
    00000001 => x"7b241073",
197
    00000002 => x"02000413",
198
    00000003 => x"98802023",
199
    00000004 => x"7b202473",
200
    00000005 => x"00100073",
201
    00000006 => x"7b241073",
202
    00000007 => x"00100413",
203
    00000008 => x"98802023",
204
    00000009 => x"98002403",
205
    00000010 => x"00847413",
206
    00000011 => x"02041263",
207
    00000012 => x"98002403",
208
    00000013 => x"00247413",
209
    00000014 => x"00041463",
210
    00000015 => x"fe9ff06f",
211
    00000016 => x"00400413",
212
    00000017 => x"98802023",
213
    00000018 => x"7b202473",
214
    00000019 => x"7b200073",
215
    00000020 => x"01000413",
216
    00000021 => x"98802023",
217
    00000022 => x"7b202473",
218 61 zero_gravi
    00000023 => x"0000100f",
219
    00000024 => x"88000067",
220 59 zero_gravi
    others   => x"00100073"  -- ebreak
221
  );
222
 
223
  -- global access control --
224
  signal acc_en : std_ulogic;
225
  signal rden   : std_ulogic;
226
  signal wren   : std_ulogic;
227
  signal maddr  : std_ulogic_vector(01 downto 0);
228
 
229
  -- data buffer --
230
  signal data_buf : std_ulogic_vector(31 downto 0);
231
 
232
  -- program buffer access --
233
  type prog_buf_t is array (0 to 3) of std_ulogic_vector(31 downto 0);
234
  signal prog_buf : prog_buf_t;
235
 
236
begin
237
 
238
  -- Debug Module Command Controller --------------------------------------------------------
239
  -- -------------------------------------------------------------------------------------------
240
  dm_controller: process(clk_i)
241
  begin
242
    if rising_edge(clk_i) then
243
      if (dm_reg.dmcontrol_dmactive = '0') or (dmi_rstn_i = '0') then -- DM reset / DM disabled
244 71 zero_gravi
        dm_ctrl.state           <= CMD_IDLE;
245
        dm_ctrl.ldsw_progbuf    <= (others => '-');
246
        dci.execute_req         <= '0';
247
        dm_ctrl.pbuf_en         <= '-';
248 59 zero_gravi
        --
249 71 zero_gravi
        dm_ctrl.illegal_cmd     <= '-';
250
        dm_ctrl.illegal_state   <= '-';
251
        dm_ctrl.cmderr          <= "000";
252 59 zero_gravi
        --
253
        dm_ctrl.hart_reset      <= '0';
254
        dm_ctrl.hart_halted     <= '0';
255
        dm_ctrl.hart_resume_req <= '0';
256
        dm_ctrl.hart_resume_ack <= '0';
257
      else -- DM active
258
 
259
        -- defaults --
260
        dci.execute_req       <= '0';
261
        dm_ctrl.illegal_cmd   <= '0';
262
        dm_ctrl.illegal_state <= '0';
263
 
264
        -- command execution fsm --
265
        case dm_ctrl.state is
266
 
267
          when CMD_IDLE => -- wait for new abstract command
268
          -- ------------------------------------------------------------
269
            if (dmi_req_valid_i = '1') and (dmi_req_op_i = '1') then -- valid DM write access
270
              if (dmi_req_addr_i = addr_command_c) then
271
                if (dm_ctrl.cmderr = "000") then -- only execute if no error
272
                  dm_ctrl.state <= CMD_EXE_CHECK;
273
                end if;
274
              end if;
275
            elsif (dm_reg.autoexec_rd = '1') or (dm_reg.autoexec_wr = '1') then -- auto execution trigger
276
              dm_ctrl.state <= CMD_EXE_CHECK;
277
            end if;
278
 
279
          when CMD_EXE_CHECK => -- check if command is valid / supported
280
          -- ------------------------------------------------------------
281
            if (dm_reg.command(31 downto 24) = x"00") and -- cmdtype: register access
282
               (dm_reg.command(23) = '0') and -- reserved
283
               (dm_reg.command(22 downto 20) = "010") and -- aarsize: has to be 32-bit
284
               (dm_reg.command(19) = '0') and -- aarpostincrement: not supported
285
               ((dm_reg.command(17) = '0') or (dm_reg.command(15 downto 05) = "00010000000")) then -- regno: only GPRs are supported: 0x1000..0x101f if transfer is set
286
              if (dm_ctrl.hart_halted = '1') then -- CPU is halted
287
                dm_ctrl.state <= CMD_EXE_PREPARE;
288
              else -- error! CPU is still running
289
                dm_ctrl.illegal_state <= '1';
290
                dm_ctrl.state         <= CMD_EXE_ERROR;
291
              end if;
292
            else -- invalid command
293
              dm_ctrl.illegal_cmd <= '1';
294
              dm_ctrl.state       <= CMD_EXE_ERROR;
295
            end if;
296
 
297
          when CMD_EXE_PREPARE => -- setup program buffer
298
          -- ------------------------------------------------------------
299
            if (dm_reg.command(17) = '1') then -- "transfer"
300
              if (dm_reg.command(16) = '0') then -- "write" = 0 -> read from GPR
301
                dm_ctrl.ldsw_progbuf <= instr_sw_c;
302
                dm_ctrl.ldsw_progbuf(31 downto 25) <= dataaddr_c(11 downto 05); -- destination address
303
                dm_ctrl.ldsw_progbuf(24 downto 20) <= dm_reg.command(4 downto 0); -- "regno" = source register
304
                dm_ctrl.ldsw_progbuf(11 downto 07) <= dataaddr_c(04 downto 00); -- destination address
305
              else -- "write" = 0 -> write to GPR
306
                dm_ctrl.ldsw_progbuf <= instr_lw_c;
307
                dm_ctrl.ldsw_progbuf(31 downto 20) <= dataaddr_c; -- source address
308
                dm_ctrl.ldsw_progbuf(11 downto 07) <= dm_reg.command(4 downto 0); -- "regno" = destination register
309
              end if;
310
            else
311 60 zero_gravi
              dm_ctrl.ldsw_progbuf <= instr_nop_c; -- NOP - do nothing
312 59 zero_gravi
            end if;
313
            --
314 60 zero_gravi
            if (dm_reg.command(18) = '1') then -- "postexec" - execute program buffer
315 59 zero_gravi
              dm_ctrl.pbuf_en <= '1';
316 60 zero_gravi
            else -- execute all program buffer entries as NOPs
317 59 zero_gravi
              dm_ctrl.pbuf_en <= '0';
318
            end if;
319
            --
320
            dm_ctrl.state <= CMD_EXE_TRIGGER;
321
 
322
          when CMD_EXE_TRIGGER => -- request CPU to execute command
323
          -- ------------------------------------------------------------
324
            dci.execute_req <= '1'; -- request execution
325
            if (dci.execute_ack = '1') then -- CPU starts execution
326
              dm_ctrl.state <= CMD_EXE_BUSY;
327
            end if;
328
 
329
          when CMD_EXE_BUSY => -- wait for CPU to finish
330
          -- ------------------------------------------------------------
331 60 zero_gravi
            if (dci.halt_ack = '1') then -- CPU is parked (halted) again -> execution done
332 59 zero_gravi
              dm_ctrl.state <= CMD_IDLE;
333
            end if;
334
 
335
          when CMD_EXE_ERROR => -- delay cycle for error to arrive abstracts.cmderr
336
          -- ------------------------------------------------------------
337
            dm_ctrl.state <= CMD_IDLE;
338
 
339
          when others => -- undefined
340
          -- ------------------------------------------------------------
341
            dm_ctrl.state <= CMD_IDLE;
342
 
343
        end case;
344
 
345
 
346 60 zero_gravi
        -- error flags --
347 59 zero_gravi
        -- ------------------------------------------------------------
348 60 zero_gravi
        if (dm_ctrl.cmderr = "000") then -- set new error
349 59 zero_gravi
          if (dm_ctrl.illegal_state = '1') then -- cannot execute since hart is not in expected state
350
            dm_ctrl.cmderr <= "100";
351
          elsif (dci.exception_ack = '1') then -- exception during execution
352
            dm_ctrl.cmderr <= "011";
353
          elsif (dm_ctrl.illegal_cmd = '1') then -- unsupported command
354
            dm_ctrl.cmderr <= "010";
355
          elsif (dm_reg.rd_acc_err = '1') or (dm_reg.wr_acc_err = '1') then -- invalid read/write while command is executing
356
            dm_ctrl.cmderr <= "001";
357
          end if;
358
        elsif (dm_reg.clr_acc_err = '1') then -- acknowledge/clear error flags
359
          dm_ctrl.cmderr <= "000";
360
        end if;
361
 
362
 
363
        -- hart status --
364
        -- ------------------------------------------------------------
365
 
366
        -- HALTED --
367
        if (dm_reg.dmcontrol_ndmreset = '1') then
368
          dm_ctrl.hart_halted <= '0';
369
        elsif (dci.halt_ack = '1') then
370
          dm_ctrl.hart_halted <= '1';
371
        elsif (dci.resume_ack = '1') then
372
          dm_ctrl.hart_halted <= '0';
373
        end if;
374
 
375
        -- RESUME REQ --
376
        if (dm_reg.dmcontrol_ndmreset = '1') then
377
          dm_ctrl.hart_resume_req <= '0';
378
        elsif (dm_reg.resume_req = '1') then
379
          dm_ctrl.hart_resume_req <= '1';
380
        elsif (dci.resume_ack = '1') then
381
          dm_ctrl.hart_resume_req <= '0';
382
        end if;
383
 
384
        -- RESUME ACK --
385
        if (dm_reg.dmcontrol_ndmreset = '1') then
386
          dm_ctrl.hart_resume_ack <= '0';
387
        elsif (dci.resume_ack = '1') then
388
          dm_ctrl.hart_resume_ack <= '1';
389
        elsif (dm_reg.resume_req = '1') then
390
          dm_ctrl.hart_resume_ack <= '0';
391
        end if;
392
 
393
        -- hart has been RESET --
394
        if (dm_reg.dmcontrol_ndmreset = '1') then
395
          dm_ctrl.hart_reset <= '1';
396
        elsif (dm_reg.reset_ack = '1') then
397
          dm_ctrl.hart_reset <= '0';
398
        end if;
399
 
400
      end if;
401
    end if;
402
  end process dm_controller;
403
 
404
  -- controller busy flag --
405
  dm_ctrl.busy <= '0' when (dm_ctrl.state = CMD_IDLE) else '1';
406
 
407
 
408
  -- Debug Module Interface - Write Access --------------------------------------------------
409
  -- -------------------------------------------------------------------------------------------
410
  dmi_write_access: process(rstn_i, clk_i)
411
  begin
412
    if (rstn_i = '0') then
413
      dm_reg.dmcontrol_ndmreset <= '0';
414
      dm_reg.dmcontrol_dmactive <= '0'; -- DM is in reset state after hardware reset
415
      --
416
      dm_reg.abstractauto_autoexecdata    <= '0';
417
      dm_reg.abstractauto_autoexecprogbuf <= "00";
418
      --
419
      dm_reg.command <= (others => '0');
420
      dm_reg.progbuf <= (others => instr_nop_c);
421
      --
422
      dm_reg.halt_req    <= '0';
423
      dm_reg.resume_req  <= '0';
424
      dm_reg.reset_ack   <= '0';
425
      dm_reg.wr_acc_err  <= '0';
426
      dm_reg.clr_acc_err <= '0';
427
      dm_reg.autoexec_wr <= '0';
428
    elsif rising_edge(clk_i) then
429
 
430
      -- default --
431
      dm_reg.resume_req  <= '0';
432
      dm_reg.reset_ack   <= '0';
433
      dm_reg.wr_acc_err  <= '0';
434
      dm_reg.clr_acc_err <= '0';
435
      dm_reg.autoexec_wr <= '0';
436
 
437
      -- DMI access --
438
      if (dmi_req_valid_i = '1') and (dmi_req_op_i = '1') then -- valid DMI write request
439
 
440
        -- debug module control --
441
        if (dmi_req_addr_i = addr_dmcontrol_c) then
442 64 zero_gravi
          dm_reg.halt_req           <= dmi_req_data_i(31); -- haltreq (-/w): write 1 to request halt; has to be cleared again by debugger
443 59 zero_gravi
          dm_reg.resume_req         <= dmi_req_data_i(30); -- resumereq (-/w1): write 1 to request resume
444
          dm_reg.reset_ack          <= dmi_req_data_i(28); -- ackhavereset (-/w1)
445
          dm_reg.dmcontrol_ndmreset <= dmi_req_data_i(01); -- ndmreset (r/w): soc reset
446
          dm_reg.dmcontrol_dmactive <= dmi_req_data_i(00); -- dmactive (r/w): DM reset
447
        end if;
448
 
449
        -- write abstract command --
450
        if (dmi_req_addr_i = addr_command_c) then
451
          if (dm_ctrl.busy = '0') and (dm_ctrl.cmderr = "000") then -- idle and no errors yet
452
            dm_reg.command <= dmi_req_data_i;
453
          end if;
454
        end if;
455
 
456
        -- write abstract command autoexec --
457
        if (dmi_req_addr_i = addr_abstractauto_c) then
458
          if (dm_ctrl.busy = '0') then -- idle and no errors yet
459
            dm_reg.abstractauto_autoexecdata       <= dmi_req_data_i(00);
460
            dm_reg.abstractauto_autoexecprogbuf(0) <= dmi_req_data_i(16);
461
            dm_reg.abstractauto_autoexecprogbuf(1) <= dmi_req_data_i(17);
462
          end if;
463
        end if;
464
 
465
        -- auto execution trigger --
466
        if ((dmi_req_addr_i = addr_data0_c)    and (dm_reg.abstractauto_autoexecdata = '1')) or
467
           ((dmi_req_addr_i = addr_progbuf0_c) and (dm_reg.abstractauto_autoexecprogbuf(0) = '1')) or
468
           ((dmi_req_addr_i = addr_progbuf1_c) and (dm_reg.abstractauto_autoexecprogbuf(1) = '1')) then
469
          dm_reg.autoexec_wr <= '1';
470
        end if;
471
 
472
        -- acknowledge command error --
473
        if (dmi_req_addr_i = addr_abstractcs_c) then
474
          if (dmi_req_data_i(10 downto 8) = "111") then
475
            dm_reg.clr_acc_err <= '1';
476
          end if;
477
        end if;
478
 
479
        -- write program buffer --
480
        if (dmi_req_addr_i(dmi_req_addr_i'left downto 1) = addr_progbuf0_c(dmi_req_addr_i'left downto 1)) then
481
          if (dm_ctrl.busy = '0') then -- idle
482
            if (dmi_req_addr_i(0) = addr_progbuf0_c(0)) then
483
              dm_reg.progbuf(0) <= dmi_req_data_i;
484
            else
485
              dm_reg.progbuf(1) <= dmi_req_data_i;
486
            end if;
487
          end if;
488
        end if;
489
 
490
        -- invalid access (while command is executing) --
491
        if (dm_ctrl.busy = '1') then -- busy
492
          if (dmi_req_addr_i = addr_abstractcs_c) or
493
             (dmi_req_addr_i = addr_command_c) or
494
             (dmi_req_addr_i = addr_abstractauto_c) or
495
             (dmi_req_addr_i = addr_data0_c) or
496
             (dmi_req_addr_i = addr_progbuf0_c) or
497
             (dmi_req_addr_i = addr_progbuf1_c) then
498
            dm_reg.wr_acc_err <= '1';
499
          end if;
500
        end if;
501
 
502
      end if;
503
    end if;
504
  end process dmi_write_access;
505
 
506
 
507
  -- Direct Control -------------------------------------------------------------------------
508
  -- -------------------------------------------------------------------------------------------
509
  -- write to abstract data register --
510
  dci.data_we <= '1' when (dmi_req_valid_i = '1') and (dmi_req_op_i = '1') and (dmi_req_addr_i = addr_data0_c) and (dm_ctrl.busy = '0') else '0';
511
  dci.wdata   <= dmi_req_data_i;
512
 
513
  -- CPU halt/resume request --
514
  cpu_halt_req_o <= dm_reg.halt_req and dm_reg.dmcontrol_dmactive; -- single shot
515
  dci.resume_req <= dm_ctrl.hart_resume_req; -- permanent
516
 
517
  -- SoC reset --
518
  cpu_ndmrstn_o <= not (dm_reg.dmcontrol_ndmreset and dm_reg.dmcontrol_dmactive);
519
 
520
  -- build program buffer array for cpu access --
521
  cpu_progbuf(0) <= dm_ctrl.ldsw_progbuf; -- pseudo program buffer for GPR access
522
  cpu_progbuf(1) <= instr_nop_c when (dm_ctrl.pbuf_en = '0') else dm_reg.progbuf(0);
523
  cpu_progbuf(2) <= instr_nop_c when (dm_ctrl.pbuf_en = '0') else dm_reg.progbuf(1);
524
  cpu_progbuf(3) <= instr_ebreak_c; -- implicit ebreak instruction
525
 
526
  -- DMI status --
527
  dmi_resp_err_o  <= '0'; -- what can go wrong?
528
  dmi_req_ready_o <= '1'; -- always ready for new read/write accesses
529
 
530
 
531
  -- Debug Module Interface - Read Access ---------------------------------------------------
532
  -- -------------------------------------------------------------------------------------------
533
  dmi_read_access: process(clk_i)
534
  begin
535
    if rising_edge(clk_i) then
536
      dmi_resp_valid_o   <= dmi_req_valid_i; -- DMI transfer ack
537
      dmi_resp_data_o    <= (others => '0'); -- default
538
      dm_reg.rd_acc_err  <= '0';
539
      dm_reg.autoexec_rd <= '0';
540
 
541
      case dmi_req_addr_i is
542
 
543
        -- debug module status register --
544
        when addr_dmstatus_c =>
545
          dmi_resp_data_o(31 downto 23) <= (others => '0'); -- reserved (r/-)
546 60 zero_gravi
          dmi_resp_data_o(22)           <= '1'; -- impebreak (r/-): there is an implicit ebreak instruction after the visible program buffer
547 59 zero_gravi
          dmi_resp_data_o(21 downto 20) <= (others => '0'); -- reserved (r/-)
548
          dmi_resp_data_o(19)           <= dm_ctrl.hart_reset; -- allhavereset (r/-): there is only one hart that can be reset
549
          dmi_resp_data_o(18)           <= dm_ctrl.hart_reset; -- anyhavereset (r/-): there is only one hart that can be reset
550
          dmi_resp_data_o(17)           <= dm_ctrl.hart_resume_ack; -- allresumeack (r/-): there is only one hart that can acknowledge resume request
551
          dmi_resp_data_o(16)           <= dm_ctrl.hart_resume_ack; -- anyresumeack (r/-): there is only one hart that can acknowledge resume request
552
          dmi_resp_data_o(15)           <= '0'; -- allnonexistent (r/-): there is only one hart that is always existent
553
          dmi_resp_data_o(14)           <= '0'; -- anynonexistent (r/-): there is only one hart that is always existent
554
          dmi_resp_data_o(13)           <= dm_reg.dmcontrol_ndmreset; -- allunavail (r/-): there is only one hart that is unavailable during reset
555
          dmi_resp_data_o(12)           <= dm_reg.dmcontrol_ndmreset; -- anyunavail (r/-): there is only one hart that is unavailable during reset
556
          dmi_resp_data_o(11)           <= not dm_ctrl.hart_halted; -- allrunning (r/-): there is only one hart that can be RUNNING or HALTED
557
          dmi_resp_data_o(10)           <= not dm_ctrl.hart_halted; -- anyrunning (r/-): there is only one hart that can be RUNNING or HALTED
558
          dmi_resp_data_o(09)           <= dm_ctrl.hart_halted; -- allhalted (r/-): there is only one hart that can be RUNNING or HALTED
559
          dmi_resp_data_o(08)           <= dm_ctrl.hart_halted; -- anyhalted (r/-): there is only one hart that can be RUNNING or HALTED
560
          dmi_resp_data_o(07)           <= '1'; -- authenticated (r/-): authentication passed since there is no authentication
561
          dmi_resp_data_o(06)           <= '0'; -- authbusy (r/-): always ready since there is no authentication
562
          dmi_resp_data_o(05)           <= '0'; -- hasresethaltreq (r/-): halt-on-reset not implemented
563
          dmi_resp_data_o(04)           <= '0'; -- confstrptrvalid (r/-): no configuration string available
564
          dmi_resp_data_o(03 downto 00) <= "0010"; -- version (r/-): compatible to version 0.13
565
 
566
        -- debug module control --
567
        when addr_dmcontrol_c =>
568
          dmi_resp_data_o(31)           <= '0'; -- haltreq (-/w): write-only
569
          dmi_resp_data_o(30)           <= '0'; -- resumereq (-/w1): write-only
570
          dmi_resp_data_o(29)           <= '0'; -- hartreset (r/w): not supported
571
          dmi_resp_data_o(28)           <= '0'; -- ackhavereset (-/w1): write-only
572
          dmi_resp_data_o(27)           <= '0'; -- reserved (r/-)
573
          dmi_resp_data_o(26)           <= '0'; -- hasel (r/-) - there is a single currently selected hart
574
          dmi_resp_data_o(25 downto 16) <= (others => '0'); -- hartsello (r/-) - there is only one hart
575
          dmi_resp_data_o(15 downto 06) <= (others => '0'); -- hartselhi (r/-) - there is only one hart
576
          dmi_resp_data_o(05 downto 04) <= (others => '0'); -- reserved (r/-)
577
          dmi_resp_data_o(03)           <= '0'; -- setresethaltreq (-/w1): halt-on-reset request - halt-on-reset not implemented
578
          dmi_resp_data_o(02)           <= '0'; -- clrresethaltreq (-/w1): halt-on-reset ack - halt-on-reset not implemented
579
          dmi_resp_data_o(01)           <= dm_reg.dmcontrol_ndmreset; -- ndmreset (r/w): soc reset
580
          dmi_resp_data_o(00)           <= dm_reg.dmcontrol_dmactive; -- dmactive (r/w): DM reset
581
 
582
        -- hart info --
583
        when addr_hartinfo_c =>
584
          dmi_resp_data_o(31 downto 24) <= (others => '0'); -- reserved (r/-)
585
          dmi_resp_data_o(23 downto 20) <= nscratch_c; -- nscratch (r/-): number of dscratch CSRs
586
          dmi_resp_data_o(19 downto 17) <= (others => '0'); -- reserved (r/-)
587
          dmi_resp_data_o(16)           <= dataaccess_c; -- dataaccess (r/-): 1: data registers are memory-mapped, 0: data reisters are CSR-mapped
588
          dmi_resp_data_o(15 downto 12) <= datasize_c; -- datasize (r/-): number data registers in memory/CSR space
589
          dmi_resp_data_o(11 downto 00) <= dataaddr_c; -- dataaddr (r/-): data registers base address (memory/CSR)
590
 
591
        -- abstract control and status --
592
        when addr_abstractcs_c =>
593
          dmi_resp_data_o(31 downto 24) <= (others => '0'); -- reserved (r/-)
594
          dmi_resp_data_o(28 downto 24) <= "00010"; -- progbufsize (r/-): number of words in program buffer = 2
595
          dmi_resp_data_o(12)           <= dm_ctrl.busy; -- busy (r/-): abstract command in progress (1) / idle (0)
596
          dmi_resp_data_o(11)           <= '0'; -- reserved (r/-)
597
          dmi_resp_data_o(10 downto 08) <= dm_ctrl.cmderr; -- cmderr (r/w1c): any error during execution?
598
          dmi_resp_data_o(07 downto 04) <= (others => '0'); -- reserved (r/-)
599
          dmi_resp_data_o(03 downto 00) <= "0001"; -- datacount (r/-): number of implemented data registers = 1
600
 
601
--      -- abstract command (-/w) --
602
--      when addr_command_c =>
603
--        dmi_resp_data_o <= (others => '0'); -- register is write-only
604
 
605
        -- abstract command autoexec (r/w) --
606
        when addr_abstractauto_c =>
607
          dmi_resp_data_o(00) <= dm_reg.abstractauto_autoexecdata; -- autoexecdata(0): read/write access to data0 triggers execution of program buffer
608
          dmi_resp_data_o(16) <= dm_reg.abstractauto_autoexecprogbuf(0); -- autoexecprogbuf(0): read/write access to progbuf0 triggers execution of program buffer
609
          dmi_resp_data_o(17) <= dm_reg.abstractauto_autoexecprogbuf(1); -- autoexecprogbuf(1): read/write access to progbuf1 triggers execution of program buffer
610
 
611
--      -- next debug module (r/-) --
612
--      when addr_nextdm_c =>
613
--        dmi_resp_data_o <= (others => '0'); -- this is the only DM
614
 
615
        -- abstract data 0 (r/w) --
616
        when addr_data0_c =>
617
          dmi_resp_data_o <= dci.rdata;
618
 
619
        -- program buffer (r/w) --
620
        when addr_progbuf0_c =>
621
          dmi_resp_data_o <= dm_reg.progbuf(0); -- program buffer 0
622
        when addr_progbuf1_c =>
623
          dmi_resp_data_o <= dm_reg.progbuf(1); -- program buffer 1
624
 
625 60 zero_gravi
--      -- system bus access control and status (r/-) --
626
--      when addr_sbcs_c =>
627
--        dmi_resp_data_o <= (others => '0'); -- bus access not implemented
628 59 zero_gravi
 
629
        -- halt summary 0 (r/-) --
630
        when addr_haltsum0_c =>
631
          dmi_resp_data_o(0) <= dm_ctrl.hart_halted; -- hart is halted
632
 
633
        -- not implemented (r/-) --
634
        when others =>
635
          dmi_resp_data_o <= (others => '0');
636
      end case;
637
 
638
      -- invalid read access (while command is executing)
639
      -- ------------------------------------------------------------
640
      if (dmi_req_valid_i = '1') and (dmi_req_op_i = '0') then -- valid DMI read request
641
        if (dm_ctrl.busy = '1') then -- busy
642
          if (dmi_req_addr_i = addr_data0_c) or
643
             (dmi_req_addr_i = addr_progbuf0_c) or
644
             (dmi_req_addr_i = addr_progbuf1_c) then
645
            dm_reg.rd_acc_err <= '1';
646
          end if;
647
        end if;
648
      end if;
649
 
650
      -- auto execution trigger --
651
      -- ------------------------------------------------------------
652
      if (dmi_req_valid_i = '1') and (dmi_req_op_i = '0') then -- valid DMI read request
653
        if ((dmi_req_addr_i = addr_data0_c)    and (dm_reg.abstractauto_autoexecdata = '1')) or
654
           ((dmi_req_addr_i = addr_progbuf0_c) and (dm_reg.abstractauto_autoexecprogbuf(0) = '1')) or
655
           ((dmi_req_addr_i = addr_progbuf1_c) and (dm_reg.abstractauto_autoexecprogbuf(1) = '1')) then
656
          dm_reg.autoexec_rd <= '1';
657
        end if;
658
      end if;
659
 
660
    end if;
661
  end process dmi_read_access;
662
 
663
 
664
  -- **************************************************************************************************************************
665
  -- CPU Bus Interface
666
  -- **************************************************************************************************************************
667
 
668
  -- Access Control ------------------------------------------------------------------------
669
  -- -------------------------------------------------------------------------------------------
670
  acc_en <= '1' when (cpu_addr_i(hi_abb_c downto lo_abb_c) = dm_base_c(hi_abb_c downto lo_abb_c)) else '0';
671 60 zero_gravi
  maddr  <= cpu_addr_i(lo_abb_c-1 downto lo_abb_c-2); -- (sub-)module select address
672 71 zero_gravi
  rden   <= acc_en and cpu_debug_i and cpu_rden_i; -- allow access only when in debug mode
673
  wren   <= acc_en and cpu_debug_i and cpu_wren_i; -- allow access only when in debug mode
674 59 zero_gravi
 
675
 
676
  -- Write Access ---------------------------------------------------------------------------
677
  -- -------------------------------------------------------------------------------------------
678
  write_access: process(clk_i)
679
  begin
680
    if rising_edge(clk_i) then
681
      -- Data buffer --
682
      if (dci.data_we = '1') then -- DM write access
683
        data_buf <= dci.wdata;
684 73 zero_gravi
      elsif (maddr = "10") and (wren = '1') then -- BUS write access
685 59 zero_gravi
        data_buf <= cpu_data_i;
686
      end if;
687
      -- Control and Status Register --
688
      dci.halt_ack      <= '0'; -- all writable flags auto-clear
689
      dci.resume_ack    <= '0';
690
      dci.execute_ack   <= '0';
691
      dci.exception_ack <= '0';
692 73 zero_gravi
      if (maddr = "11") and (wren = '1') then
693 59 zero_gravi
        dci.halt_ack      <= cpu_data_i(sreg_halt_ack_c);
694
        dci.resume_ack    <= cpu_data_i(sreg_resume_ack_c);
695
        dci.execute_ack   <= cpu_data_i(sreg_execute_ack_c);
696
        dci.exception_ack <= cpu_data_i(sreg_exception_ack_c);
697
      end if;
698
    end if;
699
  end process write_access;
700
 
701
  -- DM data buffer read access --
702
  dci.rdata <= data_buf;
703
 
704
 
705
  -- Read Access ----------------------------------------------------------------------------
706
  -- -------------------------------------------------------------------------------------------
707
  read_access: process(clk_i)
708
  begin
709
    if rising_edge(clk_i) then
710
      cpu_ack_o  <= rden or wren;
711
      cpu_data_o <= (others => '0');
712
      if (rden = '1') then -- output gate
713 60 zero_gravi
        case maddr is -- module select
714 59 zero_gravi
          when "00" => -- code ROM
715
            cpu_data_o <= code_rom_file(to_integer(unsigned(cpu_addr_i(6 downto 2))));
716
          when "01" => -- program buffer
717
            cpu_data_o <= cpu_progbuf(to_integer(unsigned(cpu_addr_i(3 downto 2))));
718
          when "10" => -- data buffer
719
            cpu_data_o <= data_buf;
720
          when others => -- status/control register
721
            cpu_data_o(sreg_resume_req_c)  <= dci.resume_req;
722
            cpu_data_o(sreg_execute_req_c) <= dci.execute_req;
723
        end case;
724
      end if;
725
    end if;
726
  end process read_access;
727
 
728
 
729
end neorv32_debug_dm_rtl;

powered by: WebSVN 2.1.0

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