Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—dbg—el2_dbg.sv Coverage Hit Total
Test Date: 27-12-2024 Toggle 91.0% 141 155
Test: all Branch 94.8% 109 115

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : // Copyright 2020 Western Digital Corporation or its affiliates.
       3              : //
       4              : // Licensed under the Apache License, Version 2.0 (the "License");
       5              : // you may not use this file except in compliance with the License.
       6              : // You may obtain a copy of the License at
       7              : //
       8              : // http://www.apache.org/licenses/LICENSE-2.0
       9              : //
      10              : // Unless required by applicable law or agreed to in writing, software
      11              : // distributed under the License is distributed on an "AS IS" BASIS,
      12              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              : // See the License for the specific language governing permissions and
      14              : // limitations under the License.
      15              : //********************************************************************************
      16              : // $Id$
      17              : //
      18              : // Function: Top level VeeR core file to control the debug mode
      19              : // Comments: Responsible to put the rest of the core in quiesce mode,
      20              : //           Send the commands/address. sends WrData and Recieve read Data.
      21              : //           And then Resume the core to do the normal mode
      22              : // Author  :
      23              : //********************************************************************************
      24              : module el2_dbg
      25              : import el2_pkg::*;
      26              : #(
      27              : `include "el2_param.vh"
      28              :  )(
      29              :    // outputs to the core for command and data interface
      30         1248 :    output logic [31:0]                 dbg_cmd_addr,
      31         1410 :    output logic [31:0]                 dbg_cmd_wrdata,
      32         2690 :    output logic                        dbg_cmd_valid,
      33          300 :    output logic                        dbg_cmd_write,             // 1: write command, 0: read_command
      34         1536 :    output logic [1:0]                  dbg_cmd_type,              // 0:gpr 1:csr 2: memory
      35          932 :    output logic [1:0]                  dbg_cmd_size,              // size of the abstract mem access debug command
      36          298 :    output logic                        dbg_core_rst_l,            // core reset from dm
      37              : 
      38              :    // inputs back from the core/dec
      39      2720050 :    input logic [31:0]                  core_dbg_rddata,
      40         2690 :    input logic                         core_dbg_cmd_done,         // This will be treated like a valid signal
      41            4 :    input logic                         core_dbg_cmd_fail,         // Exception during command run
      42              : 
      43              :    // Signals to dma to get a bubble
      44         2690 :    output logic                        dbg_dma_bubble,            // Debug needs a bubble to send a valid
      45         2690 :    input  logic                        dma_dbg_ready,             // DMA is ready to accept debug request
      46              : 
      47              :    // interface with the rest of the core to halt/resume handshaking
      48            8 :    output logic                        dbg_halt_req,              // This is a pulse
      49           10 :    output logic                        dbg_resume_req,            // Debug sends a resume requests. Pulse
      50          124 :    input  logic                        dec_tlu_debug_mode,        // Core is in debug mode
      51          126 :    input  logic                        dec_tlu_dbg_halted,        // The core has finished the queiscing sequence. Core is halted now
      52          114 :    input  logic                        dec_tlu_mpc_halted_only,   // Only halted due to MPC
      53           10 :    input  logic                        dec_tlu_resume_ack,        // core sends back an ack for the resume (pulse)
      54              : 
      55              :    // inputs from the JTAG
      56        16102 :    input logic                         dmi_reg_en,                // read or write
      57         4588 :    input logic [6:0]                   dmi_reg_addr,              // address of DM register
      58         6332 :    input logic                         dmi_reg_wr_en,             // write instruction
      59         3594 :    input logic [31:0]                  dmi_reg_wdata,             // write data
      60              : 
      61              :    // output
      62         5108 :    output logic [31:0]                 dmi_reg_rdata,             // read data
      63              : 
      64              :    // AXI Write Channels
      65          244 :    output logic                        sb_axi_awvalid,
      66          917 :    input  logic                        sb_axi_awready,
      67              :    /* exclude signals that are tied to constant value in this file */
      68              :    /*pragma coverage off*/
      69              :    output logic [pt.SB_BUS_TAG-1:0]    sb_axi_awid,
      70              :    /*pragma coverage on*/
      71          772 :    output logic [31:0]                 sb_axi_awaddr,
      72          198 :    output logic [3:0]                  sb_axi_awregion,
      73              :    /* exclude signals that are tied to constant value in this file */
      74              :    /*pragma coverage off*/
      75              :    output logic [7:0]                  sb_axi_awlen,
      76              :    /*pragma coverage on*/
      77         1228 :    output logic [2:0]                  sb_axi_awsize,
      78              :    /* exclude signals that are tied to constant value in this file */
      79              :    /*pragma coverage off*/
      80              :    output logic [1:0]                  sb_axi_awburst,
      81              :    output logic                        sb_axi_awlock,
      82              :    output logic [3:0]                  sb_axi_awcache,
      83              :    output logic [2:0]                  sb_axi_awprot,
      84              :    output logic [3:0]                  sb_axi_awqos,
      85              :    /*pragma coverage on*/
      86              : 
      87          244 :    output logic                        sb_axi_wvalid,
      88          917 :    input  logic                        sb_axi_wready,
      89          178 :    output logic [63:0]                 sb_axi_wdata,
      90         1304 :    output logic [7:0]                  sb_axi_wstrb,
      91          298 :    output logic                        sb_axi_wlast,
      92              : 
      93          244 :    input  logic                        sb_axi_bvalid,
      94          298 :    output logic                        sb_axi_bready,
      95            0 :    input  logic [1:0]                  sb_axi_bresp,
      96              : 
      97              :    // AXI Read Channels
      98         1272 :    output logic                        sb_axi_arvalid,
      99         1415 :    input  logic                        sb_axi_arready,
     100              :    /* exclude signals that are tied to constant value in this file */
     101              :    /*pragma coverage off*/
     102              :    output logic [pt.SB_BUS_TAG-1:0]    sb_axi_arid,
     103              :    /*pragma coverage on*/
     104          772 :    output logic [31:0]                 sb_axi_araddr,
     105          198 :    output logic [3:0]                  sb_axi_arregion,
     106              :    /* exclude signals that are tied to constant value in this file */
     107              :    /*pragma coverage off*/
     108              :    output logic [7:0]                  sb_axi_arlen,
     109              :    /*pragma coverage on*/
     110         1228 :    output logic [2:0]                  sb_axi_arsize,
     111              :    /* exclude signals that are tied to constant value in this file */
     112              :    /*pragma coverage off*/
     113              :    output logic [1:0]                  sb_axi_arburst,
     114              :    output logic                        sb_axi_arlock,
     115              :    output logic [3:0]                  sb_axi_arcache,
     116              :    output logic [2:0]                  sb_axi_arprot,
     117              :    output logic [3:0]                  sb_axi_arqos,
     118              :    /*pragma coverage on*/
     119              : 
     120         1272 :    input  logic                        sb_axi_rvalid,
     121              :    /* exclude signals that are tied to constant value in this file */
     122              :    /*pragma coverage off*/
     123              :    output logic                        sb_axi_rready,
     124              :    /*pragma coverage on*/
     125          990 :    input  logic [63:0]                 sb_axi_rdata,
     126            0 :    input  logic [1:0]                  sb_axi_rresp,
     127              : 
     128          297 :    input logic                         dbg_bus_clk_en,
     129              : 
     130              :    // general inputs
     131    115884880 :    input logic                         clk,
     132    115884880 :    input logic                         free_clk,
     133          299 :    input logic                         rst_l,        // This includes both top rst and debug rst
     134          297 :    input logic                         dbg_rst_l,
     135            2 :    input logic                         clk_override,
     136              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     137              :    /*pragma coverage off*/
     138              :    input logic                         scan_mode
     139              :    /*pragma coverage on*/
     140              : );
     141              : 
     142              : 
     143              :    typedef enum logic [3:0] {IDLE=4'h0, HALTING=4'h1, HALTED=4'h2, CORE_CMD_START=4'h3, CORE_CMD_WAIT=4'h4, SB_CMD_START=4'h5, SB_CMD_SEND=4'h6, SB_CMD_RESP=4'h7, CMD_DONE=4'h8, RESUMING=4'h9} state_t;
     144              :    typedef enum logic [3:0] {SBIDLE=4'h0, WAIT_RD=4'h1, WAIT_WR=4'h2, CMD_RD=4'h3, CMD_WR=4'h4, CMD_WR_ADDR=4'h5, CMD_WR_DATA=4'h6, RSP_RD=4'h7, RSP_WR=4'h8, DONE=4'h9} sb_state_t;
     145              : 
     146         5672 :    state_t       dbg_state;
     147         7298 :    state_t       dbg_nxtstate;
     148         9224 :    logic         dbg_state_en;
     149              :    // these are the registers that the debug module implements
     150          607 :    logic [31:0]  dmstatus_reg;        // [26:24]-dmerr, [17:16]-resume ack, [9:8]-halted, [3:0]-version
     151           12 :    logic [31:0]  dmcontrol_reg;       // dmcontrol register has only 6 bits implemented. 31: haltreq, 30: resumereq, 29: haltreset, 28: ackhavereset, 1: ndmreset, 0: dmactive.
     152         1236 :    logic [31:0]  command_reg;
     153         4470 :    logic [31:0]  abstractcs_reg;      // bits implemted are [12] - busy and [10:8]= command error
     154           12 :    logic [31:0]  haltsum0_reg;
     155         1410 :    logic [31:0]  data0_reg;
     156          624 :    logic [31:0]  data1_reg;
     157              : 
     158              :    // data 0
     159         2868 :    logic [31:0]  data0_din;
     160         4170 :    logic         data0_reg_wren, data0_reg_wren0, data0_reg_wren1, data0_reg_wren2;
     161              :    // data 1
     162         1320 :    logic [31:0]  data1_din;
     163         2706 :    logic         data1_reg_wren, data1_reg_wren0, data1_reg_wren1;
     164              :    // abstractcs
     165         8348 :    logic         abstractcs_busy_wren;
     166         4186 :    logic         abstractcs_busy_din;
     167            8 :    logic [2:0]   abstractcs_error_din;
     168            8 :    logic         abstractcs_error_sel0, abstractcs_error_sel1, abstractcs_error_sel2, abstractcs_error_sel3, abstractcs_error_sel4, abstractcs_error_sel5, abstractcs_error_sel6;
     169            0 :    logic         dbg_sb_bus_error;
     170              :    // abstractauto
     171            0 :    logic         abstractauto_reg_wren;
     172            0 :    logic [1:0]   abstractauto_reg;
     173              : 
     174              :    // dmstatus
     175           16 :    logic         dmstatus_resumeack_wren;
     176           10 :    logic         dmstatus_resumeack_din;
     177            8 :    logic         dmstatus_haveresetn_wren;
     178            8 :    logic         dmstatus_resumeack;
     179          597 :    logic         dmstatus_unavail;
     180          311 :    logic         dmstatus_running;
     181           12 :    logic         dmstatus_halted;
     182          302 :    logic         dmstatus_havereset, dmstatus_haveresetn;
     183              : 
     184              :    // dmcontrol
     185           10 :    logic         resumereq;
     186           76 :    logic         dmcontrol_wren, dmcontrol_wren_Q;
     187              :    // command
     188         4174 :    logic         execute_command_ns, execute_command;
     189         4174 :    logic         command_wren, command_regno_wren;
     190         2740 :    logic         command_transfer_din;
     191           74 :    logic         command_postexec_din;
     192         3888 :    logic [31:0]  command_din;
     193         1522 :    logic [3:0]   dbg_cmd_addr_incr;
     194         1248 :    logic [31:0]  dbg_cmd_curr_addr;
     195         1924 :    logic [31:0]  dbg_cmd_next_addr;
     196              : 
     197              :    // needed to send the read data back for dmi reads
     198         6480 :    logic  [31:0] dmi_reg_rdata_din;
     199              : 
     200           36 :    sb_state_t    sb_state;
     201          354 :    sb_state_t    sb_nxtstate;
     202           90 :    logic         sb_state_en;
     203              : 
     204              :    //System bus section
     205           36 :    logic              sbcs_wren;
     206           72 :    logic              sbcs_sbbusy_wren;
     207          334 :    logic              sbcs_sbbusy_din;
     208            0 :    logic              sbcs_sbbusyerror_wren;
     209          298 :    logic              sbcs_sbbusyerror_din;
     210              : 
     211            0 :    logic              sbcs_sberror_wren;
     212           36 :    logic [2:0]        sbcs_sberror_din;
     213            0 :    logic              sbcs_unaligned;
     214            0 :    logic              sbcs_illegal_size;
     215            2 :    logic [19:15]      sbcs_reg_int;
     216              : 
     217              :    // data
     218           20 :    logic              sbdata0_reg_wren0;
     219           16 :    logic              sbdata0_reg_wren1;
     220           36 :    logic              sbdata0_reg_wren;
     221           24 :    logic [31:0]       sbdata0_din;
     222              : 
     223            0 :    logic              sbdata1_reg_wren0;
     224           16 :    logic              sbdata1_reg_wren1;
     225           16 :    logic              sbdata1_reg_wren;
     226            0 :    logic [31:0]       sbdata1_din;
     227              : 
     228           36 :    logic              sbaddress0_reg_wren0;
     229           36 :    logic              sbaddress0_reg_wren1;
     230           72 :    logic              sbaddress0_reg_wren;
     231           40 :    logic [31:0]       sbaddress0_reg_din;
     232          300 :    logic [3:0]        sbaddress0_incr;
     233           16 :    logic              sbreadonaddr_access;
     234            0 :    logic              sbreadondata_access;
     235           20 :    logic              sbdata0wr_access;
     236              : 
     237         1480 :    logic              sb_abmem_cmd_done_in, sb_abmem_data_done_in;
     238         5654 :    logic              sb_abmem_cmd_done_en, sb_abmem_data_done_en;
     239         1480 :    logic              sb_abmem_cmd_done, sb_abmem_data_done;
     240          624 :    logic [31:0]       abmem_addr;
     241            2 :    logic              abmem_addr_in_dccm_region, abmem_addr_in_iccm_region, abmem_addr_in_pic_region;
     242            2 :    logic              abmem_addr_core_local;
     243          300 :    logic              abmem_addr_external;
     244              : 
     245         1516 :    logic              sb_cmd_pending, sb_abmem_cmd_pending;
     246          300 :    logic              sb_abmem_cmd_write;
     247          932 :    logic [2:0]        sb_abmem_cmd_size;
     248          624 :    logic [31:0]       sb_abmem_cmd_addr;
     249         1410 :    logic [31:0]       sb_abmem_cmd_wdata;
     250              : 
     251          300 :    logic [2:0]        sb_cmd_size;
     252           28 :    logic [31:0]       sb_cmd_addr;
     253           10 :    logic [63:0]       sb_cmd_wdata;
     254              : 
     255         1276 :    logic              sb_bus_cmd_read, sb_bus_cmd_write_addr, sb_bus_cmd_write_data;
     256         1276 :    logic              sb_bus_rsp_read, sb_bus_rsp_write;
     257            0 :    logic              sb_bus_rsp_error;
     258         1215 :    logic [63:0]       sb_bus_rdata;
     259              : 
     260              :    //registers
     261          332 :    logic [31:0]       sbcs_reg;
     262           28 :    logic [31:0]       sbaddress0_reg;
     263           10 :    logic [31:0]       sbdata0_reg;
     264            0 :    logic [31:0]       sbdata1_reg;
     265              : 
     266         1256 :    logic              sb_abmem_cmd_arvalid, sb_abmem_cmd_awvalid, sb_abmem_cmd_wvalid;
     267         1256 :    logic              sb_abmem_read_pend;
     268           20 :    logic              sb_cmd_awvalid, sb_cmd_wvalid, sb_cmd_arvalid;
     269           16 :    logic              sb_read_pend;
     270          772 :    logic [31:0]       sb_axi_addr;
     271          178 :    logic [63:0]       sb_axi_wrdata;
     272         1228 :    logic [2:0]        sb_axi_size;
     273              : 
     274            4 :    logic              dbg_dm_rst_l;
     275          299 :    logic              rst_l_sync;
     276              : 
     277              :    //clken
     278          454 :    logic              dbg_free_clken;
     279    115884880 :    logic              dbg_free_clk;
     280              : 
     281        16104 :    logic              sb_free_clken;
     282    115884880 :    logic              sb_free_clk;
     283              : 
     284              :    // clocking
     285              :    // used for the abstract commands.
     286              :    assign dbg_free_clken  = dmi_reg_en | execute_command | (dbg_state != IDLE) | dbg_state_en | dec_tlu_dbg_halted | dec_tlu_mpc_halted_only | dec_tlu_debug_mode | dbg_halt_req | clk_override;
     287              : 
     288              :    // used for the system bus
     289              :    assign sb_free_clken = dmi_reg_en | execute_command | sb_state_en | (sb_state != SBIDLE) | clk_override;
     290              : 
     291              :    rvoclkhdr dbg_free_cgc    (.en(dbg_free_clken), .l1clk(dbg_free_clk), .*);
     292              :    rvoclkhdr sb_free_cgc     (.en(sb_free_clken), .l1clk(sb_free_clk), .*);
     293              : 
     294              :    // end clocking section
     295              : 
     296              :    // Reset logic
     297              :    assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode);
     298              :    assign dbg_core_rst_l = ~dmcontrol_reg[1] | scan_mode;
     299              : 
     300              :    // synchronize the rst
     301              :    rvsyncss #(1) rstl_syncff (.din(rst_l), .dout(rst_l_sync), .clk(free_clk), .rst_l(dbg_rst_l));
     302              : 
     303              :    // system bus register
     304              :    // sbcs[31:29], sbcs - [22]:sbbusyerror, [21]: sbbusy, [20]:sbreadonaddr, [19:17]:sbaccess, [16]:sbautoincrement, [15]:sbreadondata, [14:12]:sberror, sbsize=32, 128=0, 64/32/16/8 are legal
     305              :    assign        sbcs_reg[31:29] = 3'b1;
     306              :    assign        sbcs_reg[28:23] = '0;
     307              :    assign        sbcs_reg[19:15] = {sbcs_reg_int[19], ~sbcs_reg_int[18], sbcs_reg_int[17:15]};
     308              :    assign        sbcs_reg[11:5]  = 7'h20;
     309              :    assign        sbcs_reg[4:0]   = 5'b01111;
     310              :    assign        sbcs_wren = (dmi_reg_addr ==  7'h38) & dmi_reg_en & dmi_reg_wr_en & (sb_state == SBIDLE);
     311              :    assign        sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) |
     312              :                                          (sbcs_reg[21] & dmi_reg_en & ((dmi_reg_wr_en & (dmi_reg_addr == 7'h39)) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d)));
     313              :    assign        sbcs_sbbusyerror_din = ~(sbcs_wren & dmi_reg_wdata[22]);   // Clear when writing one
     314              : 
     315              :    rvdffs #(1) sbcs_sbbusyerror_reg  (.din(sbcs_sbbusyerror_din),  .dout(sbcs_reg[22]),    .en(sbcs_sbbusyerror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     316              :    rvdffs #(1) sbcs_sbbusy_reg       (.din(sbcs_sbbusy_din),       .dout(sbcs_reg[21]),    .en(sbcs_sbbusy_wren),      .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     317              :    rvdffs #(1) sbcs_sbreadonaddr_reg (.din(dmi_reg_wdata[20]),     .dout(sbcs_reg[20]),    .en(sbcs_wren),             .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     318              :    rvdffs #(5) sbcs_misc_reg         (.din({dmi_reg_wdata[19],~dmi_reg_wdata[18],dmi_reg_wdata[17:15]}),
     319              :                                       .dout(sbcs_reg_int[19:15]), .en(sbcs_wren),             .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     320              :    rvdffs #(3) sbcs_error_reg        (.din(sbcs_sberror_din[2:0]), .dout(sbcs_reg[14:12]), .en(sbcs_sberror_wren),     .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     321              : 
     322              :    assign sbcs_unaligned =    ((sbcs_reg[19:17] == 3'b001) &  sbaddress0_reg[0]) |
     323              :                               ((sbcs_reg[19:17] == 3'b010) &  (|sbaddress0_reg[1:0])) |
     324              :                               ((sbcs_reg[19:17] == 3'b011) &  (|sbaddress0_reg[2:0]));
     325              : 
     326              :    assign sbcs_illegal_size = sbcs_reg[19];    // Anything bigger than 64 bits is illegal
     327              : 
     328              :    assign sbaddress0_incr[3:0] = ({4{(sbcs_reg[19:17] == 3'h0)}} &  4'b0001) |
     329              :                                  ({4{(sbcs_reg[19:17] == 3'h1)}} &  4'b0010) |
     330              :                                  ({4{(sbcs_reg[19:17] == 3'h2)}} &  4'b0100) |
     331              :                                  ({4{(sbcs_reg[19:17] == 3'h3)}} &  4'b1000);
     332              : 
     333              :    // sbdata
     334              :    assign        sbdata0_reg_wren0   = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3c);   // write data only when single read is 0
     335              :    assign        sbdata0_reg_wren1   = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
     336              :    assign        sbdata0_reg_wren    = sbdata0_reg_wren0 | sbdata0_reg_wren1;
     337              : 
     338              :    assign        sbdata1_reg_wren0   = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h3d);   // write data only when single read is 0;
     339              :    assign        sbdata1_reg_wren1   = (sb_state == RSP_RD) & sb_state_en & ~sbcs_sberror_wren;
     340              :    assign        sbdata1_reg_wren    = sbdata1_reg_wren0 | sbdata1_reg_wren1;
     341              : 
     342              :    assign        sbdata0_din[31:0]   = ({32{sbdata0_reg_wren0}} & dmi_reg_wdata[31:0]) |
     343              :                                        ({32{sbdata0_reg_wren1}} & sb_bus_rdata[31:0]);
     344              :    assign        sbdata1_din[31:0]   = ({32{sbdata1_reg_wren0}} & dmi_reg_wdata[31:0]) |
     345              :                                        ({32{sbdata1_reg_wren1}} & sb_bus_rdata[63:32]);
     346              : 
     347              :    rvdffe #(32)    dbg_sbdata0_reg    (.*, .din(sbdata0_din[31:0]), .dout(sbdata0_reg[31:0]), .en(sbdata0_reg_wren), .rst_l(dbg_dm_rst_l));
     348              :    rvdffe #(32)    dbg_sbdata1_reg    (.*, .din(sbdata1_din[31:0]), .dout(sbdata1_reg[31:0]), .en(sbdata1_reg_wren), .rst_l(dbg_dm_rst_l));
     349              : 
     350              :     // sbaddress
     351              :    assign        sbaddress0_reg_wren0   = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39);
     352              :    assign        sbaddress0_reg_wren    = sbaddress0_reg_wren0 | sbaddress0_reg_wren1;
     353              :    assign        sbaddress0_reg_din[31:0]= ({32{sbaddress0_reg_wren0}} & dmi_reg_wdata[31:0]) |
     354              :                                            ({32{sbaddress0_reg_wren1}} & (32'(sbaddress0_reg[31:0] + {28'b0,sbaddress0_incr[3:0]})));
     355              :    rvdffe #(32)    dbg_sbaddress0_reg    (.*, .din(sbaddress0_reg_din[31:0]), .dout(sbaddress0_reg[31:0]), .en(sbaddress0_reg_wren), .rst_l(dbg_dm_rst_l));
     356              : 
     357              :    assign sbreadonaddr_access = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h39) & sbcs_reg[20];   // if readonaddr is set the next command will start upon writing of addr0
     358              :    assign sbreadondata_access = dmi_reg_en & ~dmi_reg_wr_en & (dmi_reg_addr == 7'h3c) & sbcs_reg[15];  // if readondata is set the next command will start upon reading of data0
     359              :    assign sbdata0wr_access  = dmi_reg_en &  dmi_reg_wr_en & (dmi_reg_addr == 7'h3c);                   // write to sbdata0 will start write command to system bus
     360              : 
     361              :    // memory mapped registers
     362              :    // dmcontrol register has only 5 bits implemented. 31: haltreq, 30: resumereq, 28: ackhavereset, 1: ndmreset, 0: dmactive.
     363              :    // rest all the bits are zeroed out
     364              :    // dmactive flop is reset based on core rst_l, all other flops use dm_rst_l
     365              :    assign dmcontrol_wren      = (dmi_reg_addr ==  7'h10) & dmi_reg_en & dmi_reg_wr_en;
     366              :    assign dmcontrol_reg[29]   = '0;
     367              :    assign dmcontrol_reg[27:2] = '0;
     368              :    assign resumereq           = dmcontrol_reg[30] & ~dmcontrol_reg[31] & dmcontrol_wren_Q;
     369              :    rvdffs #(4) dmcontrolff (.din({dmi_reg_wdata[31:30],dmi_reg_wdata[28],dmi_reg_wdata[1]}), .dout({dmcontrol_reg[31:30], dmcontrol_reg[28], dmcontrol_reg[1]}), .en(dmcontrol_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     370              :    rvdffs #(1) dmcontrol_dmactive_ff (.din(dmi_reg_wdata[0]), .dout(dmcontrol_reg[0]), .en(dmcontrol_wren), .rst_l(dbg_rst_l), .clk(dbg_free_clk));
     371              :    rvdff  #(1) dmcontrol_wrenff(.din(dmcontrol_wren), .dout(dmcontrol_wren_Q), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     372              : 
     373              :    // dmstatus register bits that are implemented
     374              :    // [19:18]-havereset,[17:16]-resume ack, [9:8]-halted, [3:0]-version
     375              :    // rest all the bits are zeroed out
     376              :    //assign dmstatus_wren       = (dmi_reg_addr[31:0] ==  32'h11) & dmi_reg_en;
     377              :    assign dmstatus_reg[31:20] = '0;
     378              :    assign dmstatus_reg[19:18] = {2{dmstatus_havereset}};
     379              :    assign dmstatus_reg[15:14] = '0;
     380              :    assign dmstatus_reg[7]     = '1;
     381              :    assign dmstatus_reg[6:4]   = '0;
     382              :    assign dmstatus_reg[17:16] = {2{dmstatus_resumeack}};
     383              :    assign dmstatus_reg[13:12] = {2{dmstatus_unavail}};
     384              :    assign dmstatus_reg[11:10] = {2{dmstatus_running}};
     385              :    assign dmstatus_reg[9:8]   = {2{dmstatus_halted}};
     386              :    assign dmstatus_reg[3:0]   = 4'h2;
     387              : 
     388              :    assign dmstatus_resumeack_wren = ((dbg_state == RESUMING) & dec_tlu_resume_ack) | (dmstatus_resumeack & resumereq & dmstatus_halted);
     389              :    assign dmstatus_resumeack_din  = (dbg_state == RESUMING) & dec_tlu_resume_ack;
     390              : 
     391              :    assign dmstatus_haveresetn_wren  = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en & dmcontrol_reg[0];   // clear the havereset
     392              :    assign dmstatus_havereset        = ~dmstatus_haveresetn;
     393              : 
     394              :    assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l_sync;
     395              :    assign dmstatus_running = ~(dmstatus_unavail | dmstatus_halted);
     396              : 
     397              :    rvdffs  #(1) dmstatus_resumeack_reg  (.din(dmstatus_resumeack_din), .dout(dmstatus_resumeack), .en(dmstatus_resumeack_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     398              :    rvdff   #(1) dmstatus_halted_reg     (.din(dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only),     .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     399              :    rvdffs  #(1) dmstatus_haveresetn_reg (.din(1'b1), .dout(dmstatus_haveresetn), .en(dmstatus_haveresetn_wren), .rst_l(rst_l), .clk(dbg_free_clk));
     400              : 
     401              :    // haltsum0 register
     402              :    assign haltsum0_reg[31:1] = '0;
     403              :    assign haltsum0_reg[0]    = dmstatus_halted;
     404              : 
     405              :    // abstractcs register
     406              :    // bits implemted are [12] - busy and [10:8]= command error
     407              :    assign        abstractcs_reg[31:13] = '0;
     408              :    assign        abstractcs_reg[11]    = '0;
     409              :    assign        abstractcs_reg[7:4]   = '0;
     410              :    assign        abstractcs_reg[3:0]   = 4'h2;    // One data register
     411              : 
     412              :    assign        abstractcs_error_sel0 = abstractcs_reg[12] & ~(|abstractcs_reg[10:8]) & dmi_reg_en & ((dmi_reg_wr_en & ((dmi_reg_addr == 7'h16) | (dmi_reg_addr == 7'h17)) | (dmi_reg_addr == 7'h18)) |
     413              :                                                                                                        (dmi_reg_addr == 7'h4) | (dmi_reg_addr == 7'h5));
     414              :    assign        abstractcs_error_sel1 = execute_command & ~(|abstractcs_reg[10:8]) &
     415              :                                          ((~((command_reg[31:24] == 8'b0) | (command_reg[31:24] == 8'h2)))                      |   // Illegal command
     416              :                                           (((command_reg[22:20] == 3'b011) | (command_reg[22])) & (command_reg[31:24] == 8'h2)) |   // Illegal abstract memory size (can't be DW or higher)
     417              :                                           ((command_reg[22:20] != 3'b010) & ((command_reg[31:24] == 8'h0) & command_reg[17]))   |   // Illegal abstract reg size
     418              :                                           ((command_reg[31:24] == 8'h0) & command_reg[18]));                                          //postexec for abstract register access
     419              :    assign        abstractcs_error_sel2 = ((core_dbg_cmd_done & core_dbg_cmd_fail) |                   // exception from core
     420              :                                           (execute_command & (command_reg[31:24] == 8'h0) &           // unimplemented regs
     421              :                                                 (((command_reg[15:12] == 4'h1) & (command_reg[11:5] != 0)) | (command_reg[15:13] != 0)))) & ~(|abstractcs_reg[10:8]);
     422              :    assign        abstractcs_error_sel3 = execute_command & (dbg_state != HALTED) & ~(|abstractcs_reg[10:8]);
     423              :    assign        abstractcs_error_sel4 = dbg_sb_bus_error & dbg_bus_clk_en & ~(|abstractcs_reg[10:8]);// sb bus error for abstract memory command
     424              :    assign        abstractcs_error_sel5 = execute_command & (command_reg[31:24] == 8'h2) & ~(|abstractcs_reg[10:8]) &
     425              :                                          (((command_reg[22:20] == 3'b001) & data1_reg[0]) | ((command_reg[22:20] == 3'b010) & (|data1_reg[1:0])));  //Unaligned address for abstract memory
     426              :    assign        abstractcs_error_sel6 = (dmi_reg_addr ==  7'h16) & dmi_reg_en & dmi_reg_wr_en;
     427              : 
     428              :    assign        abstractcs_error_din[2:0]  = abstractcs_error_sel0 ? 3'b001 :                  // writing command or abstractcs while a command was executing. Or accessing data0
     429              :                                                  abstractcs_error_sel1 ? 3'b010 :               // writing a illegal command type to cmd field of command
     430              :                                                     abstractcs_error_sel2 ? 3'b011 :            // exception while running command
     431              :                                                        abstractcs_error_sel3 ? 3'b100 :         // writing a comnand when not in the halted state
     432              :                                                           abstractcs_error_sel4 ? 3'b101 :      // Bus error
     433              :                                                              abstractcs_error_sel5 ? 3'b111 :   // unaligned or illegal size abstract memory command
     434              :                                                                 abstractcs_error_sel6 ? (~dmi_reg_wdata[10:8] & abstractcs_reg[10:8]) :   //W1C
     435              :                                                                                         abstractcs_reg[10:8];                             //hold
     436              : 
     437              :    rvdffs #(1) dmabstractcs_busy_reg  (.din(abstractcs_busy_din), .dout(abstractcs_reg[12]), .en(abstractcs_busy_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     438              :    rvdff  #(3) dmabstractcs_error_reg (.din(abstractcs_error_din[2:0]), .dout(abstractcs_reg[10:8]), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     439              : 
     440              :     // abstract auto reg
     441              :    assign abstractauto_reg_wren  = dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h18) & ~abstractcs_reg[12];
     442              :    rvdffs #(2) dbg_abstractauto_reg (.*, .din(dmi_reg_wdata[1:0]), .dout(abstractauto_reg[1:0]), .en(abstractauto_reg_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
     443              : 
     444              :    // command register - implemented all the bits in this register
     445              :    // command[16] = 1: write, 0: read
     446              :    assign execute_command_ns = command_wren |
     447              :                                (dmi_reg_en & ~abstractcs_reg[12] & (((dmi_reg_addr == 7'h4) & abstractauto_reg[0]) | ((dmi_reg_addr == 7'h5) & abstractauto_reg[1])));
     448              :    assign command_wren = (dmi_reg_addr ==  7'h17) & dmi_reg_en & dmi_reg_wr_en;
     449              :    assign command_regno_wren = command_wren | ((command_reg[31:24] == 8'h0) & command_reg[19] & (dbg_state == CMD_DONE) & ~(|abstractcs_reg[10:8]));  // aarpostincrement
     450              :    assign command_postexec_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[18];
     451              :    assign command_transfer_din = (dmi_reg_wdata[31:24] == 8'h0) & dmi_reg_wdata[17];
     452              :    assign command_din[31:16] = {dmi_reg_wdata[31:24],1'b0,dmi_reg_wdata[22:19],command_postexec_din,command_transfer_din, dmi_reg_wdata[16]};
     453              :    assign command_din[15:0] =  command_wren ? dmi_reg_wdata[15:0] : dbg_cmd_next_addr[15:0];
     454              :    rvdff  #(1)  execute_commandff   (.*, .din(execute_command_ns), .dout(execute_command), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l));
     455              :    rvdffe #(16) dmcommand_reg       (.*, .din(command_din[31:16]), .dout(command_reg[31:16]), .en(command_wren), .rst_l(dbg_dm_rst_l));
     456              :    rvdffe #(16) dmcommand_regno_reg (.*, .din(command_din[15:0]),  .dout(command_reg[15:0]),  .en(command_regno_wren), .rst_l(dbg_dm_rst_l));
     457              : 
     458              :   // data0 reg
     459              :    assign data0_reg_wren0   = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h4) & (dbg_state == HALTED) & ~abstractcs_reg[12]);
     460              :    assign data0_reg_wren1   = core_dbg_cmd_done & (dbg_state == CORE_CMD_WAIT) & ~command_reg[16];
     461              :    assign data0_reg_wren    = data0_reg_wren0 | data0_reg_wren1 | data0_reg_wren2;
     462              : 
     463              :    assign data0_din[31:0]   = ({32{data0_reg_wren0}} & dmi_reg_wdata[31:0])   |
     464              :                               ({32{data0_reg_wren1}} & core_dbg_rddata[31:0]) |
     465              :                               ({32{data0_reg_wren2}} & sb_bus_rdata[31:0]);
     466              : 
     467              :    rvdffe #(32) dbg_data0_reg (.*, .din(data0_din[31:0]), .dout(data0_reg[31:0]), .en(data0_reg_wren), .rst_l(dbg_dm_rst_l));
     468              : 
     469              :    // data 1
     470              :    assign data1_reg_wren0   = (dmi_reg_en & dmi_reg_wr_en & (dmi_reg_addr == 7'h5) & (dbg_state == HALTED) & ~abstractcs_reg[12]);
     471              :    assign data1_reg_wren1   = (dbg_state == CMD_DONE) & (command_reg[31:24] == 8'h2) & command_reg[19] & ~(|abstractcs_reg[10:8]);   // aampostincrement
     472              :    assign data1_reg_wren    = data1_reg_wren0 | data1_reg_wren1;
     473              : 
     474              :    assign data1_din[31:0]   = ({32{data1_reg_wren0}} & dmi_reg_wdata[31:0]) |
     475              :                               ({32{data1_reg_wren1}} & dbg_cmd_next_addr[31:0]);
     476              : 
     477              :    rvdffe #(32)    dbg_data1_reg    (.*, .din(data1_din[31:0]), .dout(data1_reg[31:0]), .en(data1_reg_wren), .rst_l(dbg_dm_rst_l));
     478              : 
     479              :    rvdffs #(1) sb_abmem_cmd_doneff  (.din(sb_abmem_cmd_done_in),  .dout(sb_abmem_cmd_done),  .en(sb_abmem_cmd_done_en),  .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*);
     480              :    rvdffs #(1) sb_abmem_data_doneff (.din(sb_abmem_data_done_in), .dout(sb_abmem_data_done), .en(sb_abmem_data_done_en), .clk(dbg_free_clk), .rst_l(dbg_dm_rst_l), .*);
     481              : 
     482              :    // FSM to control the debug mode entry, command send/recieve, and Resume flow.
     483     42383885 :    always_comb begin
     484     42383885 :       dbg_nxtstate            = IDLE;
     485     42383885 :       dbg_state_en            = 1'b0;
     486     42383885 :       abstractcs_busy_wren    = 1'b0;
     487     42383885 :       abstractcs_busy_din     = 1'b0;
     488     42383885 :       dbg_halt_req            = dmcontrol_wren_Q & dmcontrol_reg[31];      // single pulse output to the core. Need to drive every time this register is written since core might be halted due to MPC
     489     42383885 :       dbg_resume_req          = 1'b0;                                      // single pulse output to the core
     490     42383885 :       dbg_sb_bus_error        = 1'b0;
     491     42383885 :       data0_reg_wren2         = 1'b0;
     492     42383885 :       sb_abmem_cmd_done_in    = 1'b0;
     493     42383885 :       sb_abmem_data_done_in   = 1'b0;
     494     42383885 :       sb_abmem_cmd_done_en    = 1'b0;
     495     42383885 :       sb_abmem_data_done_en   = 1'b0;
     496              : 
     497     42383885 :        case (dbg_state)
     498     38892365 :             IDLE: begin
     499     38892365 :                      dbg_nxtstate         = (dmstatus_reg[9] | dec_tlu_mpc_halted_only) ? HALTED : HALTING;         // initiate the halt command to the core
     500     38892365 :                      dbg_state_en         = dmcontrol_reg[31] | dmstatus_reg[9] | dec_tlu_mpc_halted_only;      // when the jtag writes the halt bit in the DM register, OR when the status indicates H
     501     38892365 :                      dbg_halt_req         = dmcontrol_reg[31];               // only when jtag has written the halt_req bit in the control. Removed debug mode qualification during MPC changes
     502              :             end
     503           16 :             HALTING : begin
     504           16 :                      dbg_nxtstate         = HALTED;                                 // Goto HALTED once the core sends an ACK
     505           16 :                      dbg_state_en         = dmstatus_reg[9] | dec_tlu_mpc_halted_only;     // core indicates halted
     506              :             end
     507      3477967 :             HALTED: begin
     508              :                      // wait for halted to go away before send to resume. Else start of new command
     509      3477967 :                      dbg_nxtstate         = dmstatus_reg[9] ? (resumereq ? RESUMING : (((command_reg[31:24] == 8'h2) & abmem_addr_external) ? SB_CMD_START : CORE_CMD_START)) :
     510      3477967 :                                                                                     (dmcontrol_reg[31] ? HALTING : IDLE);       // This is MPC halted case
     511      3477967 :                      dbg_state_en         = (dmstatus_reg[9] & resumereq) | execute_command | ~(dmstatus_reg[9] | dec_tlu_mpc_halted_only);
     512      3477967 :                      abstractcs_busy_wren = dbg_state_en & ((dbg_nxtstate == CORE_CMD_START) | (dbg_nxtstate == SB_CMD_START));                 // write busy when a new command was written by jtag
     513      3477967 :                      abstractcs_busy_din  = 1'b1;
     514      3477967 :                      dbg_resume_req       = dbg_state_en & (dbg_nxtstate == RESUMING);                       // single cycle pulse to core if resuming
     515              :             end
     516         1381 :             CORE_CMD_START: begin
     517              :                      // Don't execute the command if cmderror or transfer=0 for abstract register access
     518         1381 :                      dbg_nxtstate         = ((|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17])) ? CMD_DONE : CORE_CMD_WAIT;     // new command sent to the core
     519         1381 :                      dbg_state_en         = dbg_cmd_valid | (|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17]);
     520              :             end
     521         2758 :             CORE_CMD_WAIT: begin
     522         2758 :                      dbg_nxtstate         = CMD_DONE;
     523         2758 :                      dbg_state_en         = core_dbg_cmd_done;                   // go to done state for one cycle after completing current command
     524              :             end
     525          740 :             SB_CMD_START: begin
     526          740 :                      dbg_nxtstate         = (|abstractcs_reg[10:8]) ? CMD_DONE : SB_CMD_SEND;
     527          740 :                      dbg_state_en         = (dbg_bus_clk_en & ~sb_cmd_pending) | (|abstractcs_reg[10:8]);
     528              :             end
     529         1874 :             SB_CMD_SEND: begin
     530         1874 :                      sb_abmem_cmd_done_in = 1'b1;
     531         1874 :                      sb_abmem_data_done_in= 1'b1;
     532         1874 :                      sb_abmem_cmd_done_en = (sb_bus_cmd_read | sb_bus_cmd_write_addr) & dbg_bus_clk_en;
     533         1874 :                      sb_abmem_data_done_en= (sb_bus_cmd_read | sb_bus_cmd_write_data) & dbg_bus_clk_en;
     534         1874 :                      dbg_nxtstate         = SB_CMD_RESP;
     535         1874 :                      dbg_state_en         = (sb_abmem_cmd_done | sb_abmem_cmd_done_en) & (sb_abmem_data_done | sb_abmem_data_done_en) & dbg_bus_clk_en;
     536              :             end
     537         3918 :             SB_CMD_RESP: begin
     538         3918 :                      dbg_nxtstate         = CMD_DONE;
     539         3918 :                      dbg_state_en         = (sb_bus_rsp_read | sb_bus_rsp_write) & dbg_bus_clk_en;
     540         3918 :                      dbg_sb_bus_error     = (sb_bus_rsp_read | sb_bus_rsp_write) & sb_bus_rsp_error & dbg_bus_clk_en;
     541         3918 :                      data0_reg_wren2      = dbg_state_en & ~sb_abmem_cmd_write & ~dbg_sb_bus_error;
     542              :             end
     543         2845 :             CMD_DONE: begin
     544         2845 :                      dbg_nxtstate         = HALTED;
     545         2845 :                      dbg_state_en         = 1'b1;
     546         2845 :                      abstractcs_busy_wren = dbg_state_en;                    // remove the busy bit from the abstracts ( bit 12 )
     547         2845 :                      abstractcs_busy_din  = 1'b0;
     548         2845 :                      sb_abmem_cmd_done_in = 1'b0;
     549         2845 :                      sb_abmem_data_done_in= 1'b0;
     550         2845 :                      sb_abmem_cmd_done_en = 1'b1;
     551         2845 :                      sb_abmem_data_done_en= 1'b1;
     552              :             end
     553           21 :             RESUMING : begin
     554           21 :                      dbg_nxtstate            = IDLE;
     555           21 :                      dbg_state_en            = dmstatus_reg[17];             // resume ack has been updated in the dmstatus register
     556              :            end
     557              :            /* All legal values are handled above. Exclude the default part from coverage. */
     558              :            /*pragma coverage off*/
     559              :            default : begin
     560              :                      dbg_nxtstate            = IDLE;
     561              :                      dbg_state_en            = 1'b0;
     562              :                      abstractcs_busy_wren    = 1'b0;
     563              :                      abstractcs_busy_din     = 1'b0;
     564              :                      dbg_halt_req            = 1'b0;         // single pulse output to the core
     565              :                      dbg_resume_req          = 1'b0;         // single pulse output to the core
     566              :                      dbg_sb_bus_error        = 1'b0;
     567              :                      data0_reg_wren2         = 1'b0;
     568              :                      sb_abmem_cmd_done_in    = 1'b0;
     569              :                      sb_abmem_data_done_in   = 1'b0;
     570              :                      sb_abmem_cmd_done_en    = 1'b0;
     571              :                      sb_abmem_data_done_en   = 1'b0;
     572              :           end
     573              :           /*pragma coverage on*/
     574              :          endcase
     575              :    end // always_comb begin
     576              : 
     577              :    assign dmi_reg_rdata_din[31:0] = ({32{dmi_reg_addr == 7'h4}}  & data0_reg[31:0])      |
     578              :                                     ({32{dmi_reg_addr == 7'h5}}  & data1_reg[31:0])      |
     579              :                                     ({32{dmi_reg_addr == 7'h10}} & {2'b0,dmcontrol_reg[29],1'b0,dmcontrol_reg[27:0]})  |  // Read0 to Write only bits
     580              :                                     ({32{dmi_reg_addr == 7'h11}} & dmstatus_reg[31:0])   |
     581              :                                     ({32{dmi_reg_addr == 7'h16}} & abstractcs_reg[31:0]) |
     582              :                                     ({32{dmi_reg_addr == 7'h17}} & command_reg[31:0])    |
     583              :                                     ({32{dmi_reg_addr == 7'h18}} & {30'h0,abstractauto_reg[1:0]})    |
     584              :                                     ({32{dmi_reg_addr == 7'h40}} & haltsum0_reg[31:0])   |
     585              :                                     ({32{dmi_reg_addr == 7'h38}} & sbcs_reg[31:0])       |
     586              :                                     ({32{dmi_reg_addr == 7'h39}} & sbaddress0_reg[31:0]) |
     587              :                                     ({32{dmi_reg_addr == 7'h3c}} & sbdata0_reg[31:0])    |
     588              :                                     ({32{dmi_reg_addr == 7'h3d}} & sbdata1_reg[31:0]);
     589              : 
     590              : 
     591              :    rvdffs #($bits(state_t)) dbg_state_reg    (.din(dbg_nxtstate), .dout({dbg_state}), .en(dbg_state_en), .rst_l(dbg_dm_rst_l & rst_l), .clk(dbg_free_clk));
     592              :    rvdffe #(32)             dmi_rddata_reg   (.din(dmi_reg_rdata_din[31:0]), .dout(dmi_reg_rdata[31:0]), .en(dmi_reg_en), .rst_l(dbg_dm_rst_l), .clk(clk), .*);
     593              : 
     594              :    assign abmem_addr[31:0]      = data1_reg[31:0];
     595              :    assign abmem_addr_core_local = (abmem_addr_in_dccm_region | abmem_addr_in_iccm_region | abmem_addr_in_pic_region);
     596              :    assign abmem_addr_external   = ~abmem_addr_core_local;
     597              : 
     598              :    assign abmem_addr_in_dccm_region = (abmem_addr[31:28] == pt.DCCM_REGION) & pt.DCCM_ENABLE;
     599              :    assign abmem_addr_in_iccm_region = (abmem_addr[31:28] == pt.ICCM_REGION) & pt.ICCM_ENABLE;
     600              :    assign abmem_addr_in_pic_region  = (abmem_addr[31:28] == pt.PIC_REGION);
     601              : 
     602              :    // interface for the core
     603              :    assign dbg_cmd_addr[31:0]    = (command_reg[31:24] == 8'h2) ? data1_reg[31:0]  : {20'b0, command_reg[11:0]};
     604              :    assign dbg_cmd_wrdata[31:0]  = data0_reg[31:0];
     605              :    assign dbg_cmd_valid         = (dbg_state == CORE_CMD_START) & ~((|abstractcs_reg[10:8]) | ((command_reg[31:24] == 8'h0) & ~command_reg[17]) | ((command_reg[31:24] == 8'h2) & abmem_addr_external)) & dma_dbg_ready;
     606              :    assign dbg_cmd_write         = command_reg[16];
     607              :    assign dbg_cmd_type[1:0]     = (command_reg[31:24] == 8'h2) ? 2'b10 : {1'b0, (command_reg[15:12] == 4'b0)};
     608              :    assign dbg_cmd_size[1:0]     = command_reg[21:20];
     609              : 
     610              :    assign dbg_cmd_addr_incr[3:0]  = (command_reg[31:24] == 8'h2) ? (4'h1 << sb_abmem_cmd_size[1:0]) : 4'h1;
     611              :    assign dbg_cmd_curr_addr[31:0] = (command_reg[31:24] == 8'h2) ? data1_reg[31:0]  : {16'b0, command_reg[15:0]};
     612              :    assign dbg_cmd_next_addr[31:0] = dbg_cmd_curr_addr[31:0] + {28'h0,dbg_cmd_addr_incr[3:0]};
     613              : 
     614              :    // Ask DMA to stop taking bus trxns since debug request is done
     615              :    assign dbg_dma_bubble = ((dbg_state == CORE_CMD_START) & ~(|abstractcs_reg[10:8])) | (dbg_state == CORE_CMD_WAIT);
     616              : 
     617              :    assign sb_cmd_pending       = (sb_state == CMD_RD) | (sb_state == CMD_WR) | (sb_state == CMD_WR_ADDR) | (sb_state == CMD_WR_DATA) | (sb_state == RSP_RD) | (sb_state == RSP_WR);
     618              :    assign sb_abmem_cmd_pending = (dbg_state == SB_CMD_START) | (dbg_state == SB_CMD_SEND) | (dbg_state== SB_CMD_RESP);
     619              : 
     620              : 
     621              :   // system bus FSM
     622     42383885 :   always_comb begin
     623     42383885 :       sb_nxtstate            = SBIDLE;
     624     42383885 :       sb_state_en            = 1'b0;
     625     42383885 :       sbcs_sbbusy_wren       = 1'b0;
     626     42383885 :       sbcs_sbbusy_din        = 1'b0;
     627     42383885 :       sbcs_sberror_wren      = 1'b0;
     628     42383885 :       sbcs_sberror_din[2:0]  = 3'b0;
     629     42383885 :       sbaddress0_reg_wren1   = 1'b0;
     630     42383885 :       case (sb_state)
     631     42383697 :             SBIDLE: begin
     632     42383697 :                      sb_nxtstate            = sbdata0wr_access ? WAIT_WR : WAIT_RD;
     633     42383697 :                      sb_state_en            = (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(|sbcs_reg[14:12]) & ~sbcs_reg[22];
     634     42383697 :                      sbcs_sbbusy_wren       = sb_state_en;                                                 // set the single read bit if it is a singlread command
     635     42383697 :                      sbcs_sbbusy_din        = 1'b1;
     636     42383697 :                      sbcs_sberror_wren      = sbcs_wren & (|dmi_reg_wdata[14:12]);                                            // write to clear the error bits
     637     42383697 :                      sbcs_sberror_din[2:0]  = ~dmi_reg_wdata[14:12] & sbcs_reg[14:12];
     638              :             end
     639            8 :             WAIT_RD: begin
     640            8 :                      sb_nxtstate           = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_RD;
     641            8 :                      sb_state_en           = (dbg_bus_clk_en & ~sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size;
     642            8 :                      sbcs_sberror_wren     = sbcs_unaligned | sbcs_illegal_size;
     643            8 :                      sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100;
     644              :             end
     645           10 :             WAIT_WR: begin
     646           10 :                      sb_nxtstate           = (sbcs_unaligned | sbcs_illegal_size) ? DONE : CMD_WR;
     647           10 :                      sb_state_en           = (dbg_bus_clk_en & ~sb_abmem_cmd_pending) | sbcs_unaligned | sbcs_illegal_size;
     648           10 :                      sbcs_sberror_wren     = sbcs_unaligned | sbcs_illegal_size;
     649           10 :                      sbcs_sberror_din[2:0] = sbcs_unaligned ? 3'b011 : 3'b100;
     650              :             end
     651           20 :             CMD_RD : begin
     652           20 :                      sb_nxtstate           = RSP_RD;
     653           20 :                      sb_state_en           = sb_bus_cmd_read & dbg_bus_clk_en;
     654              :             end
     655           25 :             CMD_WR : begin
     656           25 :                      sb_nxtstate           = (sb_bus_cmd_write_addr & sb_bus_cmd_write_data) ? RSP_WR : (sb_bus_cmd_write_data ? CMD_WR_ADDR : CMD_WR_DATA);
     657           25 :                      sb_state_en           = (sb_bus_cmd_write_addr | sb_bus_cmd_write_data) & dbg_bus_clk_en;
     658              :             end
     659            0 :             CMD_WR_ADDR : begin
     660            0 :                      sb_nxtstate           = RSP_WR;
     661            0 :                      sb_state_en           = sb_bus_cmd_write_addr & dbg_bus_clk_en;
     662              :             end
     663            0 :             CMD_WR_DATA : begin
     664            0 :                      sb_nxtstate           = RSP_WR;
     665            0 :                      sb_state_en           = sb_bus_cmd_write_data & dbg_bus_clk_en;
     666              :             end
     667           44 :             RSP_RD: begin
     668           44 :                      sb_nxtstate           = DONE;
     669           44 :                      sb_state_en           = sb_bus_rsp_read & dbg_bus_clk_en;
     670           44 :                      sbcs_sberror_wren     = sb_state_en & sb_bus_rsp_error;
     671           44 :                      sbcs_sberror_din[2:0] = 3'b010;
     672              :             end
     673           45 :             RSP_WR: begin
     674           45 :                      sb_nxtstate           = DONE;
     675           45 :                      sb_state_en           = sb_bus_rsp_write & dbg_bus_clk_en;
     676           45 :                      sbcs_sberror_wren     = sb_state_en & sb_bus_rsp_error;
     677           45 :                      sbcs_sberror_din[2:0] = 3'b010;
     678              :             end
     679           36 :             DONE: begin
     680           36 :                      sb_nxtstate            = SBIDLE;
     681           36 :                      sb_state_en            = 1'b1;
     682           36 :                      sbcs_sbbusy_wren       = 1'b1;                           // reset the single read
     683           36 :                      sbcs_sbbusy_din        = 1'b0;
     684           36 :                      sbaddress0_reg_wren1   = sbcs_reg[16] & (sbcs_reg[14:12] == 3'b0);    // auto increment was set and no error. Update to new address after completing the current command
     685              :             end
     686              :             /* All legal values are handled above. Exclude the default part from coverage. */
     687              :             /*pragma coverage off*/
     688              :             default : begin
     689              :                      sb_nxtstate            = SBIDLE;
     690              :                      sb_state_en            = 1'b0;
     691              :                      sbcs_sbbusy_wren       = 1'b0;
     692              :                      sbcs_sbbusy_din        = 1'b0;
     693              :                      sbcs_sberror_wren      = 1'b0;
     694              :                      sbcs_sberror_din[2:0]  = 3'b0;
     695              :                      sbaddress0_reg_wren1   = 1'b0;
     696              :            end
     697              :             /*pragma coverage on*/
     698              :          endcase
     699              :    end // always_comb begin
     700              : 
     701              :    rvdffs #($bits(sb_state_t)) sb_state_reg (.din(sb_nxtstate), .dout({sb_state}), .en(sb_state_en), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
     702              : 
     703              :    assign sb_abmem_cmd_write      = command_reg[16];
     704              :    assign sb_abmem_cmd_size[2:0]  = {1'b0, command_reg[21:20]};
     705              :    assign sb_abmem_cmd_addr[31:0] = abmem_addr[31:0];
     706              :    assign sb_abmem_cmd_wdata[31:0] = data0_reg[31:0];
     707              : 
     708              :    assign sb_cmd_size[2:0]   = sbcs_reg[19:17];
     709              :    assign sb_cmd_wdata[63:0] = {sbdata1_reg[31:0], sbdata0_reg[31:0]};
     710              :    assign sb_cmd_addr[31:0]  = sbaddress0_reg[31:0];
     711              : 
     712              :    assign sb_abmem_cmd_awvalid    = (dbg_state == SB_CMD_SEND) & sb_abmem_cmd_write & ~sb_abmem_cmd_done;
     713              :    assign sb_abmem_cmd_wvalid     = (dbg_state == SB_CMD_SEND) & sb_abmem_cmd_write & ~sb_abmem_data_done;
     714              :    assign sb_abmem_cmd_arvalid    = (dbg_state == SB_CMD_SEND) & ~sb_abmem_cmd_write & ~sb_abmem_cmd_done & ~sb_abmem_data_done;
     715              :    assign sb_abmem_read_pend      = (dbg_state == SB_CMD_RESP) & ~sb_abmem_cmd_write;
     716              : 
     717              :    assign sb_cmd_awvalid     = ((sb_state == CMD_WR) | (sb_state == CMD_WR_ADDR));
     718              :    assign sb_cmd_wvalid      = ((sb_state == CMD_WR) | (sb_state == CMD_WR_DATA));
     719              :    assign sb_cmd_arvalid     = (sb_state == CMD_RD);
     720              :    assign sb_read_pend       = (sb_state == RSP_RD);
     721              : 
     722              :    assign sb_axi_size[2:0]    = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend) ? sb_abmem_cmd_size[2:0] : sb_cmd_size[2:0];
     723              :    assign sb_axi_addr[31:0]   = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid | sb_abmem_cmd_arvalid | sb_abmem_read_pend) ? sb_abmem_cmd_addr[31:0] : sb_cmd_addr[31:0];
     724              :    assign sb_axi_wrdata[63:0] = (sb_abmem_cmd_awvalid | sb_abmem_cmd_wvalid) ? {2{sb_abmem_cmd_wdata[31:0]}} : sb_cmd_wdata[63:0];
     725              : 
     726              :    // Generic bus response signals
     727              :    assign sb_bus_cmd_read       = sb_axi_arvalid & sb_axi_arready;
     728              :    assign sb_bus_cmd_write_addr = sb_axi_awvalid & sb_axi_awready;
     729              :    assign sb_bus_cmd_write_data = sb_axi_wvalid  & sb_axi_wready;
     730              : 
     731              :    assign sb_bus_rsp_read  = sb_axi_rvalid & sb_axi_rready;
     732              :    assign sb_bus_rsp_write = sb_axi_bvalid & sb_axi_bready;
     733              :    assign sb_bus_rsp_error = (sb_bus_rsp_read & (|(sb_axi_rresp[1:0]))) | (sb_bus_rsp_write & (|(sb_axi_bresp[1:0])));
     734              : 
     735              :    // AXI Request signals
     736              :    assign sb_axi_awvalid              = sb_abmem_cmd_awvalid | sb_cmd_awvalid;
     737              :    assign sb_axi_awaddr[31:0]         = sb_axi_addr[31:0];
     738              :    assign sb_axi_awid[pt.SB_BUS_TAG-1:0] = '0;
     739              :    assign sb_axi_awsize[2:0]          = sb_axi_size[2:0];
     740              :    assign sb_axi_awprot[2:0]          = 3'b001;
     741              :    assign sb_axi_awcache[3:0]         = 4'b1111;
     742              :    assign sb_axi_awregion[3:0]        = sb_axi_addr[31:28];
     743              :    assign sb_axi_awlen[7:0]           = '0;
     744              :    assign sb_axi_awburst[1:0]         = 2'b01;
     745              :    assign sb_axi_awqos[3:0]           = '0;
     746              :    assign sb_axi_awlock               = '0;
     747              : 
     748              :    assign sb_axi_wvalid       = sb_abmem_cmd_wvalid | sb_cmd_wvalid;
     749              :    assign sb_axi_wdata[63:0]  = ({64{(sb_axi_size[2:0] == 3'h0)}} & {8{sb_axi_wrdata[7:0]}}) |
     750              :                                 ({64{(sb_axi_size[2:0] == 3'h1)}} & {4{sb_axi_wrdata[15:0]}}) |
     751              :                                 ({64{(sb_axi_size[2:0] == 3'h2)}} & {2{sb_axi_wrdata[31:0]}}) |
     752              :                                 ({64{(sb_axi_size[2:0] == 3'h3)}} & {sb_axi_wrdata[63:0]});
     753              :    assign sb_axi_wstrb[7:0]   = ({8{(sb_axi_size[2:0] == 3'h0)}} & (8'h1 << sb_axi_addr[2:0])) |
     754              :                                 ({8{(sb_axi_size[2:0] == 3'h1)}} & (8'h3 << {sb_axi_addr[2:1],1'b0})) |
     755              :                                 ({8{(sb_axi_size[2:0] == 3'h2)}} & (8'hf << {sb_axi_addr[2],2'b0})) |
     756              :                                 ({8{(sb_axi_size[2:0] == 3'h3)}} & 8'hff);
     757              :    assign sb_axi_wlast        = '1;
     758              : 
     759              :    assign sb_axi_arvalid              = sb_abmem_cmd_arvalid | sb_cmd_arvalid;
     760              :    assign sb_axi_araddr[31:0]         = sb_axi_addr[31:0];
     761              :    assign sb_axi_arid[pt.SB_BUS_TAG-1:0] = '0;
     762              :    assign sb_axi_arsize[2:0]          = sb_axi_size[2:0];
     763              :    assign sb_axi_arprot[2:0]          = 3'b001;
     764              :    assign sb_axi_arcache[3:0]         = 4'b0;
     765              :    assign sb_axi_arregion[3:0]        = sb_axi_addr[31:28];
     766              :    assign sb_axi_arlen[7:0]           = '0;
     767              :    assign sb_axi_arburst[1:0]         = 2'b01;
     768              :    assign sb_axi_arqos[3:0]           = '0;
     769              :    assign sb_axi_arlock               = '0;
     770              : 
     771              :    // AXI Response signals
     772              :    assign sb_axi_bready = 1'b1;
     773              : 
     774              :    assign sb_axi_rready = 1'b1;
     775              :    assign sb_bus_rdata[63:0] = ({64{sb_axi_size == 3'h0}} & ((sb_axi_rdata[63:0] >>  8*sb_axi_addr[2:0]) & 64'hff))       |
     776              :                                ({64{sb_axi_size == 3'h1}} & ((sb_axi_rdata[63:0] >> 16*sb_axi_addr[2:1]) & 64'hffff))    |
     777              :                                ({64{sb_axi_size == 3'h2}} & ((sb_axi_rdata[63:0] >> 32*sb_axi_addr[2]) & 64'hffff_ffff)) |
     778              :                                ({64{sb_axi_size == 3'h3}} & sb_axi_rdata[63:0]);
     779              : 
     780              : `ifdef RV_ASSERT_ON
     781              : // assertion.
     782              : //  when the resume_ack is asserted then the dec_tlu_dbg_halted should be 0
     783              :    dm_check_resume_and_halted: assert property (@(posedge clk)  disable iff(~rst_l) (~dec_tlu_resume_ack | ~dec_tlu_dbg_halted));
     784              : 
     785              :    assert_b2b_haltreq: assert property (@(posedge clk) disable iff (~(rst_l)) (##1 dbg_halt_req |=> ~dbg_halt_req));  // One cycle delay to fix weird issue around reset
     786              :    assert_halt_resume_onehot: assert #0 ($onehot0({dbg_halt_req, dbg_resume_req}));
     787              : `endif
     788              : endmodule