module_icg_en[8:0], 14'b0};
//for ifu control
assign cp0_ifu_icg_en = module_icg_en[0];
assign cp0_idu_icg_en = module_icg_en[1];
assign cp0_iu_icg_en  = module_icg_en[2];
assign cp0_hpcp_icg_en = module_icg_en[2];
assign cp0_lsu_icg_en = module_icg_en[3];
assign cp0_pmp_icg_en = module_icg_en[4];
assign cp0_biu_icg_en = module_icg_en[5];
assign cp0_rtu_icg_en = module_icg_en[6];
assign cp0_fpu_icg_en = module_icg_en[7];
assign cp0_dtu_icg_en     = module_icg_en[8];
//==========================================================
//               Define the MRADDR register
//  Machine Register
//  32-bit Machine Mode Read/Write
//  the definiton for MRADDR register is listed as follows
//==========================================================
assign mraddr_value[31:0] = sysio_cp0_rst_addr[31:0];

//==========================================================
//               Define the MEXSTATUS register
//  Machine Register
//  32-bit Machine Mode Read/Write
//  the definiton for MEXSTATUS register is listed as follows
//==========================================================
assign rstmd_in[1:0] = &iui_regs_wdata_srst[1:0] ? 2'b0 : iui_regs_wdata_srst[1:0];
// Use individed signal to opt timing.

always @ (posedge regs_clk or negedge cpurst_b)
begin
  if (!cpurst_b) begin
    mexstatus_rstmd[1:0] <= 2'b0;
    mexstatus_lpmd[1:0]  <= 2'b0;
    mexstatus_wfeen      <= 1'b1;
  end
  else if (mexstatus_local_en) begin
    mexstatus_rstmd[1:0] <= rstmd_in[1:0];
    mexstatus_lpmd[1:0]  <= {1'b0, iui_regs_wdata[2]};
    mexstatus_wfeen      <= iui_regs_wdata[4];
  end
end
assign srst_vld = mexstatus_local_en && |rstmd_in[1:0];

always @ (posedge regs_clk or negedge cpurst_b)
begin
  if (!cpurst_b) begin
    mexstatus_spushen    <= 1'b0;
    mexstatus_spswapen   <= 1'b0;
  end
  else if (mexstatus_local_en) begin
    mexstatus_spushen    <= iui_regs_wdata[16];
    mexstatus_spswapen   <= iui_regs_wdata[17];
  end
end

always @ (posedge regs_flush_clk or negedge cpurst_b)
begin
  if (!cpurst_b)
    mexstatus_expt <= 1'b0;
  else if (mexstatus_local_en && rtu_yy_xx_dbgon)
    mexstatus_expt <= iui_regs_wdata[5];
  else if (rtu_cp0_lockup_clr)
    mexstatus_expt <= 1'b0;
  else if (rtu_yy_xx_expt_vld && !rtu_yy_xx_expt_int && !rtu_cp0_nmi_vld)
    mexstatus_expt <= 1'b1;
  else if (iui_regs_inst_mret && !mexstatus_nmi && !regs_cpu_in_int)
    mexstatus_expt <= 1'b0;
end

always @ (posedge regs_flush_clk or negedge cpurst_b)
begin
  if (!cpurst_b)
    mexstatus_nmi <= 1'b0;
  else if (mexstatus_local_en && rtu_yy_xx_dbgon)
    mexstatus_nmi <= iui_regs_wdata[7];
  else if (rtu_cp0_lockup_clr)
    mexstatus_nmi <= 1'b0;
  else if (rtu_cp0_nmi_vld)
    mexstatus_nmi <= 1'b1;
  else if (iui_regs_inst_mret)
    mexstatus_nmi <= 1'b0;
end

always @ (posedge regs_flush_clk or negedge cpurst_b)
begin
  if (!cpurst_b)
    mexstatus_bus_err <= 1'b0;
  else if (rtu_yy_xx_expt_vld && !rtu_yy_xx_expt_int)
    mexstatus_bus_err <= rtu_cp0_bus_error;
  else if (mexstatus_local_en)
    mexstatus_bus_err <= iui_regs_wdata[8];
end

always @ (posedge regs_flush_clk or negedge cpurst_b)
begin
  if (!cpurst_b)
    mexstatus_lockup <= 1'b0;
  else if (rtu_cp0_lockup_clr)
    mexstatus_lockup <= 1'b0;
  else if (rtu_cp0_lockup_vld)
    mexstatus_lockup <= 1'b1;
end

assign mexstatus_value[31:0] = {14'b0, mexstatus_spswapen, mexstatus_spushen,
                                7'b0, mexstatus_bus_err, mexstatus_nmi, mexstatus_lockup, mexstatus_expt,
                                mexstatus_wfeen, mexstatus_lpmd[1:0], mexstatus_rstmd[1:0]};

// MNMICAUSE, MNMIPC is in trap_csr.

//==========================================================
// CP0 Extension CSR Module
//==========================================================
assign inv_sm_clk_en = regs_doing_inv
                    || special_regs_inv_sm_clk_en
                    || inst_dcache_op
                    || icache_inv_req;

// &Instance("gated_clk_cell", "x_inv_sm_gated_clk"); @307
gated_clk_cell  x_inv_sm_gated_clk (
  .clk_in              (forever_cpuclk     ),
  .clk_out             (inv_sm_clk         ),
  .external_en         (1'b0               ),
  .global_en           (special_regs_clk_en),
  .local_en            (1'b0               ),
  .module_en           (inv_sm_clk_en      ),
  .pad_yy_icg_scan_en  (pad_yy_icg_scan_en )
);

// &Connect(.clk_in      (forever_cpuclk), @308
//          .external_en (1'b0), @309
//          .global_en   (special_regs_clk_en), @310
//          .module_en   (inv_sm_clk_en), @311
//          .local_en    (1'b0), @312
//          .clk_out     (inv_sm_clk)); @313
// &Force("output", "inv_sm_clk"); @314

parameter RST_IDLE = 2'b00;
parameter RST_WFC  = 2'b01;
parameter RST_DONE = 2'b10;
//==========================================================
//              FSM of reset cache inv cctl logic
//==========================================================
always @(posedge inv_sm_clk or negedge cpurst_b)
begin
  if(!cpurst_b)
    rst_cache_inv[1:0] <= RST_IDLE;
  else
    rst_cache_inv[1:0] <= rst_cache_inv_nxt[1:0];
end

// &CombBeg; @330
always @( rst_cache_inv
       or rst_inv_done
       or ifu_cp0_rst_inv_req)
begin
case(rst_cache_inv)
  RST_IDLE:
  begin
    if(ifu_cp0_rst_inv_req)
      rst_cache_inv_nxt[1:0] = RST_WFC;
    else
      rst_cache_inv_nxt[1:0] = RST_IDLE;
  end
  RST_WFC:
  begin
    if(rst_inv_done)
      rst_cache_inv_nxt[1:0] = RST_IDLE;
    else
      rst_cache_inv_nxt[1:0] = RST_WFC;
  end
  default:
  begin
    rst_cache_inv_nxt[1:0] = RST_IDLE;
  end
endcase
// &CombEnd; @351
end

assign rst_inv_done         = rst_icache_inv[1:0] == RST_IDLE && 
                              rst_dcache_inv[1:0] == RST_IDLE && 
                              rst_bht_inv[1:0] == RST_IDLE;
assign cp0_ifu_rst_inv_done = rst_cache_inv[1:0] == RST_IDLE && !ifu_cp0_rst_inv_req;

//==========================================================
//                ICache Operation
//==========================================================
assign inst_icache_op = ext_inst_ifu_icc_req
                     || special_icache_inv;

assign icache_inv_req = (ifu_cp0_rst_inv_req | inst_icache_op) & (rst_bht_inv[1:0] == RST_IDLE);

always @(posedge inv_sm_clk or negedge cpurst_b)
begin
  if(!cpurst_b)
    rst_icache_inv[1:0] <= RST_IDLE;
  else
    rst_icache_inv[1:0] <= rst_icache_inv_nxt[1:0];
end

// &CombBeg; @374
always @( rst_icache_inv
       or ext_ifu_inv_done
       or ifu_cp0_icache_inv_done
       or icache_inv_req)
begin
case(rst_icache_inv)
  RST_IDLE:
  begin
    if(icache_inv_req)      
      rst_icache_inv_nxt[1:0] = RST_WFC;
    else
      rst_icache_inv_nxt[1:0] = RST_IDLE;
  end
  RST_WFC:
  begin
    if(ifu_cp0_icache_inv_done)
      rst_icache_inv_nxt[1:0] = RST_DONE;
    else
      rst_icache_inv_nxt[1:0] = RST_WFC;
  end
  RST_DONE:
    if (ext_ifu_inv_done)
      rst_icache_inv_nxt[1:0] = RST_IDLE;
    else
      rst_icache_inv_nxt[1:0] = RST_DONE;
  default:
  begin
    rst_icache_inv_nxt[1:0] = RST_IDLE;
  end
endcase
// &CombEnd; @400
end

//assign icache_sm_idle    = rst_icache_inv[1:0] == RST_IDLE;
//assign icache_sm_done    = rst_icache_inv[1:0] == RST_DONE;
//assign icache_op_done    = icache_sm_idle & ~icache_inv_req |
//                           icache_sm_done;

assign bht_inv_req = (ifu_cp0_rst_inv_req | inst_icache_op) & (rst_icache_inv[1:0] == RST_IDLE);

always @(posedge inv_sm_clk or negedge cpurst_b)
begin
  if(!cpurst_b)
    rst_bht_inv[1:0] <= RST_IDLE;
  else
    rst_bht_inv[1:0] <= rst_bht_inv_nxt[1:0];
end

// &CombBeg; @417
always @( bht_inv_req
       or ext_ifu_inv_done
       or ifu_cp0_bht_inv_done
       or rst_bht_inv)
begin
case(rst_bht_inv)
  RST_IDLE:
  begin
    if(bht_inv_req)
      rst_bht_inv_nxt[1:0] = RST_WFC;
    else
      rst_bht_inv_nxt[1:0] = RST_IDLE;
  end
  RST_WFC:
  begin
    if(ifu_cp0_bht_inv_done)
      rst_bht_inv_nxt[1:0] = RST_DONE;
    else
      rst_bht_inv_nxt[1:0] = RST_WFC;
  end
  RST_DONE:
    if (ext_ifu_inv_done)
      rst_bht_inv_nxt[1:0] = RST_IDLE;
    else
      rst_bht_inv_nxt[1:0] = RST_DONE;
  default:
  begin
    rst_bht_inv_nxt[1:0] = RST_IDLE;
  end
endcase
// &CombEnd; @443
end
//assign bht_sm_idle    = rst_bht_inv[1:0] == RST_IDLE;
//assign bht_sm_done    = rst_bht_inv[1:0] == RST_DONE;
//assign bht_op_done    = bht_sm_idle & ~bht_inv_req |
//                        bht_sm_done;
//==========================================================
//                DCache Operation
//==========================================================
assign inst_dcache_op = ext_inst_lsu_icc_req
                     || special_dcache_clean;

always @(posedge inv_sm_clk or negedge cpurst_b)
begin
  if(!cpurst_b)
    rst_dcache_inv[1:0] <= RST_IDLE;
  else
    rst_dcache_inv[1:0] <= rst_dcache_inv_nxt[1:0];
end

// &CombBeg; @462
always @( inst_dcache_op
       or rst_dcache_inv
       or ifu_cp0_rst_inv_req
       or lsu_cp0_icc_done)
begin
case(rst_dcache_inv)
  RST_IDLE:
  begin
    if(ifu_cp0_rst_inv_req)
      rst_dcache_inv_nxt[1:0] = RST_WFC;
    else if (inst_dcache_op)
      rst_dcache_inv_nxt[1:0] = RST_WFC;
    else
      rst_dcache_inv_nxt[1:0] = RST_IDLE;
  end
  RST_WFC:
  begin
    if(lsu_cp0_icc_done)
      rst_dcache_inv_nxt[1:0] = RST_DONE;
    else
      rst_dcache_inv_nxt[1:0] = RST_WFC;
  end
  RST_DONE:
    rst_dcache_inv_nxt[1:0] = RST_IDLE;
  default:
  begin
    rst_dcache_inv_nxt[1:0] = RST_IDLE;
  end
endcase
// &CombEnd; @487
end

//assign dcache_sm_idle    = rst_dcache_inv[1:0] == RST_IDLE;
//assign dcache_sm_done    = rst_dcache_inv[1:0] == RST_DONE;
//assign dcache_op_done    = dcache_sm_idle & ~dcache_inv_req |
//                           dcache_sm_done;
                           
assign regs_doing_inv = ifu_cp0_rst_inv_req
                     || !rst_inv_done
                     || rst_dcache_inv[1:0] != RST_IDLE
                     || rst_icache_inv[1:0] != RST_IDLE
                     || rst_bht_inv[1:0] != RST_IDLE
                     || rst_cache_inv[1:0] != RST_IDLE;

assign ext_ifu_inv_done = rst_bht_inv[1:0] == RST_DONE
                       && rst_icache_inv[1:0] == RST_DONE;

assign ext_inst_ifu_inv_done = ext_ifu_inv_done;
assign special_icache_inv_done = ext_ifu_inv_done;
assign ext_inst_lsu_icc_done = rst_dcache_inv[1:0] == RST_WFC && lsu_cp0_icc_done
                            || rst_dcache_inv[1:0] == RST_IDLE && !inst_dcache_op;

assign icache_rst_inv_req  = rst_icache_inv[1:0] == RST_WFC;
assign bht_rst_inv_req     = rst_bht_inv[1:0]    == RST_WFC;
assign dcache_rst_inv_req  = rst_dcache_inv[1:0] == RST_WFC;

assign cp0_lsu_icc_req        = dcache_rst_inv_req;
assign cp0_lsu_icc_type[1:0]  = ext_inst_lsu_icc_req ? ext_inst_lsu_icc_type[1:0]
                                                     : 2'b0;
assign cp0_lsu_icc_addr[31:0] = ext_inst_lsu_icc_req ? ext_inst_lsu_icc_addr[31:0]
                                                     : 32'b0;
assign cp0_lsu_icc_op[1:0]    = ext_inst_lsu_icc_req ? ext_inst_lsu_icc_op[1:0]
                              : special_dcache_clean ? 2'b10               // Clean Dcache
                                                     : 2'b01;              // Inv Dcache

assign cp0_ifu_btb_clr = 1'b0;
assign cp0_ifu_btb_en  = l0btb;
assign cp0_ifu_bht_inv = bht_rst_inv_req;
assign cp0_ifu_bht_en  = bpe;
assign cp0_ifu_ras_en  = rs;


// &Force("nonport", "cp0_ifu_btb_clr"); @531
// &Force("nonport", "cp0_ifu_btb_en"); @532

// &Force("nonport", "cp0_ifu_bht_inv"); @537
// &Force("nonport", "cp0_ifu_bht_en"); @538

// &Force("nonport", "cp0_ifu_ras_en"); @543




//==========================================================
// Rename for Output
//==========================================================
// Output to LSU
assign cp0_lsu_dcache_en = de;
assign cp0_lsu_dcache_wb = wb;
assign cp0_lsu_dcache_wa = wa;

assign cp0_ifu_icache_en = ie;
assign cp0_ifu_icache_inv_req = icache_rst_inv_req;
assign cp0_ifu_icache_inv_type = ext_inst_ifu_icc_req ? ext_inst_ifu_icc_type
                                                      : 1'b0;
assign cp0_ifu_icache_inv_addr[31:0] = ext_inst_ifu_icc_addr[31:0];
// &Force("nonport", "icache_rst_inv_req"); @572

// AEE means Accurated Expt, So Async Expt is !mhint_aee.
assign cp0_xx_async_expt_en = !mhint_aee;

//==========================================================
//                      Output for CP0
//==========================================================
assign regs_special_lpmd[1:0] = mexstatus_lpmd[1:0];
assign regs_srst_srstmd[1:0] = mexstatus_rstmd[1:0];
assign regs_srst_srst_vld = srst_vld;
assign regs_spswap_en = mexstatus_spswapen;
assign regs_cpu_in_nmi = mexstatus_nmi;

//==========================================================
//                      Output for RTU
//==========================================================
assign cp0_rtu_wfe_en = mexstatus_wfeen;
assign cp0_rtu_in_expt = mexstatus_expt;

//==========================================================
//                      Output for IDU
//==========================================================
assign cp0_idu_spec_push_en  = mexstatus_spushen;
assign cp0_idu_swap_sp_en    = mexstatus_spswapen;

//output to dbg infor
assign rst_top_op_done       = rst_inv_done;
//----------------------------------------------------------
//                         For DTU
//----------------------------------------------------------
//assign cp0_dtu_icg_en     = module_icg_en[8];

assign cp0_dtu_pcfifo_frz = pcfifo_freeze;
// &ModuleEnd; @607
endmodule