data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v
1: b'%Error: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:180: Cannot find file containing module: \'sync\'\nsync  x_cpu2pmu_sync1 (\n^~~~\n        ... Looked in:\n             data/full_repos/permissive/418752214/smart_run/logical/pmu,data/full_repos/permissive/418752214/sync\n             data/full_repos/permissive/418752214/smart_run/logical/pmu,data/full_repos/permissive/418752214/sync.v\n             data/full_repos/permissive/418752214/smart_run/logical/pmu,data/full_repos/permissive/418752214/sync.sv\n             sync\n             sync.v\n             sync.sv\n             obj_dir/sync\n             obj_dir/sync.v\n             obj_dir/sync.sv\n%Error: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:195: Cannot find file containing module: \'sync\'\nsync  x_cpu2pmu_sync2 (\n^~~~\n%Warning-WIDTH: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:221: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                                    : ... In instance pmu\n    if (!apb_pmu_paddr[11:0] )\n        ^\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:242: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s SEL generates 12 bits.\n                                                                                    : ... In instance pmu\n  if(!apb_pmu_paddr[11:0] )\n     ^\n%Error: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:322: Cannot find file containing module: \'tap2_sm\'\ntap2_sm  x_tap2_sm (\n^~~~~~~\n%Error: data/full_repos/permissive/418752214/smart_run/logical/pmu/pmu.v:333: Cannot find file containing module: \'px_had_sync\'\npx_had_sync  x_jtag2pmu_sync (\n^~~~~~~~~~~\n%Error: Exiting due to 4 error(s), 2 warning(s)\n'
module pmu(
  apb_pmu_paddr,
  apb_pmu_penable,
  apb_pmu_psel,
  apb_pmu_pwdata,
  apb_pmu_pwrite,
  biu_pad_lpmd_b,
  corec_pmu_sleep_out,
  cpu_clk,
  gate_en0,
  gate_en1,
  had_pad_wakeup_req_b,
  i_pad_cpu_jtg_rst_b,
  i_pad_jtg_tclk,
  intraw_vld,
  pad_cpu_rst_b,
  pad_had_jdb_req_b,
  pad_had_jtg_tap_en,
  pad_had_jtg_tms,
  pad_had_jtg_trst_b,
  pad_had_jtg_trst_b_pre,
  pg_reset_b,
  pmu_apb_prdata,
  pmu_clk,


  pmu_cpu_pwr_on, 
  pmu_cpu_iso_in, 
  pmu_cpu_iso_out, 
  pmu_cpu_save, 
  pmu_cpu_restore
);


input   [11:0]  apb_pmu_paddr;         
input           apb_pmu_penable;       
input           apb_pmu_psel;          
input   [31:0]  apb_pmu_pwdata;        
input           apb_pmu_pwrite;        
input   [1 :0]  biu_pad_lpmd_b;        
input           corec_pmu_sleep_out;   
input           cpu_clk;               
input           had_pad_wakeup_req_b;  
input           i_pad_cpu_jtg_rst_b;   
input           i_pad_jtg_tclk;        
input           intraw_vld;            
input           pad_cpu_rst_b;         
input           pad_had_jtg_tap_en;    
input           pad_had_jtg_tms;       
input           pad_had_jtg_trst_b_pre; 
input           pmu_clk;               
output          gate_en0;              
output          gate_en1;              
output          pad_had_jdb_req_b;     
output          pad_had_jtg_trst_b;    
output          pg_reset_b;            
output  [31:0]  pmu_apb_prdata;        


output          pmu_cpu_pwr_on; 
output          pmu_cpu_iso_in; 
output          pmu_cpu_iso_out; 
output          pmu_cpu_save;
output          pmu_cpu_restore;


reg     [31:0]  counter;               
reg             counter_en_ff;         
reg     [31:0]  counter_load;          
reg     [31:0]  ctrl_reg;              
reg     [2 :0]  cur_state;             
reg             debug_pending;         
reg             event_ff;              
reg             event_pending;         
reg     [2 :0]  next_state;            
reg     [2 :0]  pg_next_state;         
reg     [2 :0]  pg_state;              
reg     [31:0]  pmu_apb_prdata;        


reg     [31:0]  pmu_lp_mode_sel;


wire    [11:0]  apb_pmu_paddr;         
wire            apb_pmu_penable;       
wire            apb_pmu_psel;          
wire    [31:0]  apb_pmu_pwdata;        
wire            apb_pmu_pwrite;        
wire    [1 :0]  biu_pad_lpmd_b;        
wire            corec_pmu_sleep_out;   
wire            counter_en;            
wire            cpu_clk;               
wire            debug_ctl_en;          
wire            debug_vld;             
wire            debug_vld_pre;         
wire            debug_wake_vld;        
wire            doze_mode;             
wire            event_ctl_en;          
wire            event_vld;             
wire            gate_en0;              
wire            gate_en1;              
wire            had_pad_wakeup_req_b;  
wire            i_pad_cpu_jtg_rst_b;   
wire            i_pad_jtg_tclk;        
wire            intraw_vld;            
wire            load_cnt_en;           
wire            low_power_dis;         
wire            low_power_dis_pre;     
wire            lpmd_en;               
wire            lpmd_en_ff;            
wire            pad_cpu_rst_b;         
wire            pad_had_jdb_req_b;     
wire            pad_had_jtg_tap_en;    
wire            pad_had_jtg_tms;       
wire            pad_had_jtg_trst_b;    
wire            pad_had_jtg_trst_b_pre; 
wire            pad_vic_event_vld;     
wire            pg_reset_b;            
wire            pmu_clk;


reg            pmu_cpu_pwr_on; 
reg            pmu_cpu_iso_in; 
reg            pmu_cpu_iso_out; 
reg            pmu_cpu_save;
reg            pmu_cpu_restore;

wire            pmu_debug_wakeup;      
wire            pmu_event_wakeup;      
wire            pmu_wakeup;            
wire            pmu_wic_wakeup;        
wire            stop_mode;             
wire            wait_mode;             
wire            wic_ctl_en;            


wire            pmu_lp_mode_normal;
wire            pmu_lp_mode_clk_slow;
wire            pmu_lp_mode_clk_off;
wire            pmu_lp_mode_ret_pwr_off;
wire            pmu_lp_mode_pwr_off;


parameter NORMAL_MODE      = 3'b000;
parameter LIGHT_SLP_MODE   = 3'b001;
parameter LSLP_TO_NORMAL   = 3'b010;
parameter DEEP_SLP_MODE    = 3'b011;
parameter DSLP_TO_NORMAL   = 3'b100;

parameter PG_IDLE          = 3'b000;
parameter PG_RESET_ON      = 3'b001;
parameter PG_ISO_ON        = 3'b010;
parameter PG_POWER_OFF_REQ = 3'b011;
parameter PG_POWER_OFF     = 3'b100;
parameter PG_POWER_ON      = 3'b101;
parameter PG_ISO_OFF       = 3'b110;
parameter PG_RESET_OFF     = 3'b111;

assign low_power_dis_pre = (biu_pad_lpmd_b[1:0] == 2'b11);

assign lpmd_en = (biu_pad_lpmd_b[1:0] != 2'b11) ;



sync  x_cpu2pmu_sync1 (
  .fast_clk      (cpu_clk      ),
  .in            (lpmd_en      ),
  .out           (lpmd_en_ff   ),
  .pad_cpu_rst_b (pad_cpu_rst_b),
  .slow_clk      (pmu_clk      )
);








sync  x_cpu2pmu_sync2 (
  .fast_clk          (cpu_clk          ),
  .in                (low_power_dis_pre),
  .out               (low_power_dis    ),
  .pad_cpu_rst_b     (pad_cpu_rst_b    ),
  .slow_clk          (pmu_clk          )
);










always @ (posedge pmu_clk or negedge pad_cpu_rst_b)
begin
if (!pad_cpu_rst_b)
  begin
    ctrl_reg[31:0] <= 32'b0;
    pmu_lp_mode_sel[31:0] <= 32'b0;
  end
else if (apb_pmu_psel && apb_pmu_pwrite && apb_pmu_penable)
  begin
    if (!apb_pmu_paddr[11:0] )
      ctrl_reg[31:0] <= apb_pmu_pwdata[31:0];
    else if (apb_pmu_paddr[11:0] == 12'h4 )
      counter_load[31:0] <= apb_pmu_pwdata[31:0];
    else if (apb_pmu_paddr[11:0] == 12'h8 )
      pmu_lp_mode_sel[31:0]    <=  cur_state[2:0] == NORMAL_MODE ? apb_pmu_pwdata[31:0] : pmu_lp_mode_sel[31:0];
  end
end





always @( apb_pmu_paddr[11:0]
       or ctrl_reg[3:0]
       or apb_pmu_psel
       or apb_pmu_pwrite
       or counter[31:0])
begin
if (apb_pmu_psel && !apb_pmu_pwrite) 
begin
  if(!apb_pmu_paddr[11:0] )
    pmu_apb_prdata[31:0] = {28'b0,ctrl_reg[3:0]};
  else if (apb_pmu_paddr[11:0] == 12'h4 )
    pmu_apb_prdata[31:0] = counter[31:0];
  else if (apb_pmu_paddr[11:0] == 12'h8 )
    pmu_apb_prdata[31:0] = pmu_lp_mode_sel[31:0];
  else
    pmu_apb_prdata[31:0] = 32'b0;
end

end

assign wic_ctl_en = ctrl_reg[0];
assign event_ctl_en = ctrl_reg[1];
assign debug_ctl_en = ctrl_reg[2];
assign counter_en = ctrl_reg[3];


always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    counter_en_ff <=0;
  end
  else
  begin
    counter_en_ff <=counter_en ;
  end
end

assign load_cnt_en= (counter_en && !counter_en_ff)
                    || !(|counter[31:0]);

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    counter[31:0] <= 32'h0;
  end
  else if (load_cnt_en)
  begin
    counter[31:0] <= counter_load[31:0];
  end
  else if (counter_en)
     counter[31:0] <= counter[31:0] -1'b1;
  else
     counter[31:0] <= counter[31:0];
end

assign pad_vic_event_vld = (counter[31:0] == 32'b0) && counter_en;


assign pmu_wic_wakeup = intraw_vld && wic_ctl_en && lpmd_en_ff ;



assign event_vld = pad_vic_event_vld && !event_ff && lpmd_en_ff ;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    event_ff <= 1'b0;
  else
    event_ff <= pad_vic_event_vld;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    event_pending <= 1'b0;
  else if (event_vld)
    event_pending <= 1'b1;
  else if (low_power_dis)
    event_pending <= 1'b0;
end

assign pmu_event_wakeup = event_pending && event_ctl_en ;



tap2_sm  x_tap2_sm (
  .debug_wake_vld      (debug_wake_vld     ),
  .pad_had_jtg_tap_en  (pad_had_jtg_tap_en ),
  .tclk                (i_pad_jtg_tclk     ),
  .tms_i               (pad_had_jtg_tms    ),
  .trst_b              (i_pad_cpu_jtg_rst_b)
);

assign debug_vld_pre = (debug_wake_vld || !had_pad_wakeup_req_b) && lpmd_en_ff;


px_had_sync  x_jtag2pmu_sync (
  .clk1                   (i_pad_jtg_tclk        ),
  .clk2                   (pmu_clk               ),
  .rst1_b                 (pad_had_jtg_trst_b_pre),
  .rst2_b                 (pad_cpu_rst_b         ),
  .sync_in                (debug_vld_pre         ),
  .sync_out               (debug_vld             )
);

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    debug_pending <= 1'b0;
  else if (debug_vld)
    debug_pending <= 1'b1;
  else if (low_power_dis)
    debug_pending <= 1'b0;
end
 
assign pad_had_jdb_req_b = !debug_pending;
assign pmu_debug_wakeup = debug_pending && debug_ctl_en ;

assign pmu_wakeup = pmu_event_wakeup || pmu_wic_wakeup || pmu_debug_wakeup ;


assign pmu_lp_mode_pwr_off       = pmu_lp_mode_sel[4];
assign pmu_lp_mode_ret_pwr_off   = pmu_lp_mode_sel[3];
assign pmu_lp_mode_clk_off       = pmu_lp_mode_sel[2];
assign pmu_lp_mode_clk_slow      = pmu_lp_mode_sel[1];
assign pmu_lp_mode_normal        = pmu_lp_mode_sel[0];



wire normal_req;


wire cpu_slp_req;
assign normal_req    = biu_pad_lpmd_b[1:0] == 2'b11;


assign cpu_slp_req   = biu_pad_lpmd_b[1:0] != 2'b11;

reg         dslp_in_sequence_req;
reg         dslp_in_sequence_done; 
reg         dslp_out_sequence_req;
reg         dslp_out_sequence_done; 
reg [15:0]  dslp_sequence_counter;
reg         dslp_sequence_counter_enable;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    cur_state[2:0] <= NORMAL_MODE;
  else
    cur_state[2:0] <= next_state[2:0];
end

always @(*) begin
  case(cur_state)
  NORMAL_MODE:
    begin
      if(pmu_lp_mode_normal) 
        next_state = NORMAL_MODE;
      else if(pmu_lp_mode_clk_slow || pmu_lp_mode_clk_off)
        if(cpu_slp_req)
          next_state = LIGHT_SLP_MODE;
        else
          next_state = NORMAL_MODE;
      else if(pmu_lp_mode_ret_pwr_off || pmu_lp_mode_pwr_off)
        if(cpu_slp_req)
          next_state = DEEP_SLP_MODE;
        else
          next_state = NORMAL_MODE;
      else
        next_state = NORMAL_MODE;
    end
  LIGHT_SLP_MODE:
    begin
      if(pmu_wakeup)
        next_state = LSLP_TO_NORMAL;
      else
        next_state = LIGHT_SLP_MODE;
    end
  LSLP_TO_NORMAL:
    begin
      if(normal_req)
        next_state = NORMAL_MODE;
      else
        next_state = LSLP_TO_NORMAL;
    end
  DEEP_SLP_MODE:
    begin
      if(pmu_wakeup && dslp_in_sequence_done)
        next_state = DSLP_TO_NORMAL;
      else
        next_state = DEEP_SLP_MODE;
    end
  DSLP_TO_NORMAL:
    begin
      if(normal_req && dslp_out_sequence_done)
        next_state = NORMAL_MODE;
      else
        next_state = DSLP_TO_NORMAL;
    end
  endcase
end









assign gate_en0 = (cur_state[2:0] == LIGHT_SLP_MODE) && pmu_lp_mode_clk_slow ? 1 : 0;
assign gate_en1 = (cur_state[2:0] == LIGHT_SLP_MODE && pmu_lp_mode_clk_off) ||
                  (cur_state[2:0] == DEEP_SLP_MODE  && pmu_lp_mode_ret_pwr_off) 
                  ? 1 : 0;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b) begin
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b0;
  end
  else if (cur_state[2:0] == NORMAL_MODE && next_state[2:0] == DEEP_SLP_MODE) begin
    dslp_in_sequence_req    <= 1'b1;
    dslp_out_sequence_req   <= 1'b0;
  end
  else if (cur_state[2:0] == DEEP_SLP_MODE && next_state[2:0] == DSLP_TO_NORMAL) begin
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b1;
  end
  else begin 
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b0;
  end
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
    dslp_sequence_counter_enable    <= 1'b0;
  else if (dslp_in_sequence_req || dslp_out_sequence_req)
    dslp_sequence_counter_enable    <= 1'b1;
  else if (dslp_in_sequence_done || dslp_out_sequence_done)
    dslp_sequence_counter_enable    <= 1'b0;
  else
    dslp_sequence_counter_enable    <= dslp_sequence_counter_enable;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
    dslp_sequence_counter[15:0]    <= 16'h0;
  else if (dslp_sequence_counter_enable)
    dslp_sequence_counter[15:0]    <= dslp_sequence_counter[15:0] + 1'b1;
  else
    dslp_sequence_counter[15:0]    <= 16'h0;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    pmu_cpu_pwr_on    <= 1'b1; 
    pmu_cpu_iso_in    <= 1'b0; 
    pmu_cpu_iso_out   <= 1'b0; 
    pmu_cpu_save      <= 1'b0;
    pmu_cpu_restore   <= 1'b0;

    dslp_in_sequence_done  <= 1'b0;
    dslp_out_sequence_done <= 1'b0;
  end
  else if (cur_state[2:0] == DEEP_SLP_MODE)
  begin
    pmu_cpu_restore        <= 1'b0;
    dslp_out_sequence_done <= 1'b0;

    case(dslp_sequence_counter[15:0])
    16'h1:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h20:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h40:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b1;
      end
    16'h41:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h60:
      begin
        pmu_cpu_pwr_on     <= 1'b0; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;

        dslp_in_sequence_done <= 1'b1;
      end
    default:
      begin
        pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
        pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
        pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
        pmu_cpu_save       <= pmu_cpu_save   ;

        dslp_in_sequence_done <= dslp_in_sequence_done;
      end
    endcase
  end
  else if (cur_state[2:0] == DSLP_TO_NORMAL)
  begin
    pmu_cpu_save           <= 1'b0;
    dslp_in_sequence_done  <= 1'b0;

    case(dslp_sequence_counter[15:0])
    16'h1:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h20:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b1;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h21:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h40:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h60:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b1;
      end
    default:
      begin
        pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
        pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
        pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
        pmu_cpu_restore    <= pmu_cpu_restore   ;

        dslp_out_sequence_done <= dslp_out_sequence_done;
      end
    endcase
  end
  else
  begin
    pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
    pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
    pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
    pmu_cpu_save       <= pmu_cpu_save   ;
    pmu_cpu_restore    <= pmu_cpu_restore;

    dslp_in_sequence_done  <= dslp_in_sequence_done;
    dslp_out_sequence_done <= dslp_out_sequence_done;
  end
end



assign pg_reset_b          = pad_cpu_rst_b;
assign pad_had_jtg_trst_b  = pad_had_jtg_trst_b_pre;

endmodule
module pmu(
  apb_pmu_paddr,
  apb_pmu_penable,
  apb_pmu_psel,
  apb_pmu_pwdata,
  apb_pmu_pwrite,
  biu_pad_lpmd_b,
  corec_pmu_sleep_out,
  cpu_clk,
  gate_en0,
  gate_en1,
  had_pad_wakeup_req_b,
  i_pad_cpu_jtg_rst_b,
  i_pad_jtg_tclk,
  intraw_vld,
  pad_cpu_rst_b,
  pad_had_jdb_req_b,
  pad_had_jtg_tap_en,
  pad_had_jtg_tms,
  pad_had_jtg_trst_b,
  pad_had_jtg_trst_b_pre,
  pg_reset_b,
  pmu_apb_prdata,
  pmu_clk,


  pmu_cpu_pwr_on, 
  pmu_cpu_iso_in, 
  pmu_cpu_iso_out, 
  pmu_cpu_save, 
  pmu_cpu_restore
);



input   [11:0]  apb_pmu_paddr;         
input           apb_pmu_penable;       
input           apb_pmu_psel;          
input   [31:0]  apb_pmu_pwdata;        
input           apb_pmu_pwrite;        
input   [1 :0]  biu_pad_lpmd_b;        
input           corec_pmu_sleep_out;   
input           cpu_clk;               
input           had_pad_wakeup_req_b;  
input           i_pad_cpu_jtg_rst_b;   
input           i_pad_jtg_tclk;        
input           intraw_vld;            
input           pad_cpu_rst_b;         
input           pad_had_jtg_tap_en;    
input           pad_had_jtg_tms;       
input           pad_had_jtg_trst_b_pre; 
input           pmu_clk;               
output          gate_en0;              
output          gate_en1;              
output          pad_had_jdb_req_b;     
output          pad_had_jtg_trst_b;    
output          pg_reset_b;            
output  [31:0]  pmu_apb_prdata;        


output          pmu_cpu_pwr_on; 
output          pmu_cpu_iso_in; 
output          pmu_cpu_iso_out; 
output          pmu_cpu_save;
output          pmu_cpu_restore;


reg     [31:0]  counter;               
reg             counter_en_ff;         
reg     [31:0]  counter_load;          
reg     [31:0]  ctrl_reg;              
reg     [2 :0]  cur_state;             
reg             debug_pending;         
reg             event_ff;              
reg             event_pending;         
reg     [2 :0]  next_state;            
reg     [2 :0]  pg_next_state;         
reg     [2 :0]  pg_state;              
reg     [31:0]  pmu_apb_prdata;        


reg     [31:0]  pmu_lp_mode_sel;


wire    [11:0]  apb_pmu_paddr;         
wire            apb_pmu_penable;       
wire            apb_pmu_psel;          
wire    [31:0]  apb_pmu_pwdata;        
wire            apb_pmu_pwrite;        
wire    [1 :0]  biu_pad_lpmd_b;        
wire            corec_pmu_sleep_out;   
wire            counter_en;            
wire            cpu_clk;               
wire            debug_ctl_en;          
wire            debug_vld;             
wire            debug_vld_pre;         
wire            debug_wake_vld;        
wire            doze_mode;             
wire            event_ctl_en;          
wire            event_vld;             
wire            gate_en0;              
wire            gate_en1;              
wire            had_pad_wakeup_req_b;  
wire            i_pad_cpu_jtg_rst_b;   
wire            i_pad_jtg_tclk;        
wire            intraw_vld;            
wire            load_cnt_en;           
wire            low_power_dis;         
wire            low_power_dis_pre;     
wire            lpmd_en;               
wire            lpmd_en_ff;            
wire            pad_cpu_rst_b;         
wire            pad_had_jdb_req_b;     
wire            pad_had_jtg_tap_en;    
wire            pad_had_jtg_tms;       
wire            pad_had_jtg_trst_b;    
wire            pad_had_jtg_trst_b_pre; 
wire            pad_vic_event_vld;     
wire            pg_reset_b;            
wire            pmu_clk;


reg            pmu_cpu_pwr_on; 
reg            pmu_cpu_iso_in; 
reg            pmu_cpu_iso_out; 
reg            pmu_cpu_save;
reg            pmu_cpu_restore;

wire            pmu_debug_wakeup;      
wire            pmu_event_wakeup;      
wire            pmu_wakeup;            
wire            pmu_wic_wakeup;        
wire            stop_mode;             
wire            wait_mode;             
wire            wic_ctl_en;            


wire            pmu_lp_mode_normal;
wire            pmu_lp_mode_clk_slow;
wire            pmu_lp_mode_clk_off;
wire            pmu_lp_mode_ret_pwr_off;
wire            pmu_lp_mode_pwr_off;


parameter NORMAL_MODE      = 3'b000;
parameter LIGHT_SLP_MODE   = 3'b001;
parameter LSLP_TO_NORMAL   = 3'b010;
parameter DEEP_SLP_MODE    = 3'b011;
parameter DSLP_TO_NORMAL   = 3'b100;

parameter PG_IDLE          = 3'b000;
parameter PG_RESET_ON      = 3'b001;
parameter PG_ISO_ON        = 3'b010;
parameter PG_POWER_OFF_REQ = 3'b011;
parameter PG_POWER_OFF     = 3'b100;
parameter PG_POWER_ON      = 3'b101;
parameter PG_ISO_OFF       = 3'b110;
parameter PG_RESET_OFF     = 3'b111;

assign low_power_dis_pre = (biu_pad_lpmd_b[1:0] == 2'b11);

assign lpmd_en = (biu_pad_lpmd_b[1:0] != 2'b11) ;



sync  x_cpu2pmu_sync1 (
  .fast_clk      (cpu_clk      ),
  .in            (lpmd_en      ),
  .out           (lpmd_en_ff   ),
  .pad_cpu_rst_b (pad_cpu_rst_b),
  .slow_clk      (pmu_clk      )
);








sync  x_cpu2pmu_sync2 (
  .fast_clk          (cpu_clk          ),
  .in                (low_power_dis_pre),
  .out               (low_power_dis    ),
  .pad_cpu_rst_b     (pad_cpu_rst_b    ),
  .slow_clk          (pmu_clk          )
);










always @ (posedge pmu_clk or negedge pad_cpu_rst_b)
begin
if (!pad_cpu_rst_b)
  begin
    ctrl_reg[31:0] <= 32'b0;
    pmu_lp_mode_sel[31:0] <= 32'b0;
  end
else if (apb_pmu_psel && apb_pmu_pwrite && apb_pmu_penable)
  begin
    if (!apb_pmu_paddr[11:0] )
      ctrl_reg[31:0] <= apb_pmu_pwdata[31:0];
    else if (apb_pmu_paddr[11:0] == 12'h4 )
      counter_load[31:0] <= apb_pmu_pwdata[31:0];
    else if (apb_pmu_paddr[11:0] == 12'h8 )
      pmu_lp_mode_sel[31:0]    <=  cur_state[2:0] == NORMAL_MODE ? apb_pmu_pwdata[31:0] : pmu_lp_mode_sel[31:0];
  end
end





always @( apb_pmu_paddr[11:0]
       or ctrl_reg[3:0]
       or apb_pmu_psel
       or apb_pmu_pwrite
       or counter[31:0])
begin
if (apb_pmu_psel && !apb_pmu_pwrite) 
begin
  if(!apb_pmu_paddr[11:0] )
    pmu_apb_prdata[31:0] = {28'b0,ctrl_reg[3:0]};
  else if (apb_pmu_paddr[11:0] == 12'h4 )
    pmu_apb_prdata[31:0] = counter[31:0];
  else if (apb_pmu_paddr[11:0] == 12'h8 )
    pmu_apb_prdata[31:0] = pmu_lp_mode_sel[31:0];
  else
    pmu_apb_prdata[31:0] = 32'b0;
end

end

assign wic_ctl_en = ctrl_reg[0];
assign event_ctl_en = ctrl_reg[1];
assign debug_ctl_en = ctrl_reg[2];
assign counter_en = ctrl_reg[3];


always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    counter_en_ff <=0;
  end
  else
  begin
    counter_en_ff <=counter_en ;
  end
end

assign load_cnt_en= (counter_en && !counter_en_ff)
                    || !(|counter[31:0]);

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    counter[31:0] <= 32'h0;
  end
  else if (load_cnt_en)
  begin
    counter[31:0] <= counter_load[31:0];
  end
  else if (counter_en)
     counter[31:0] <= counter[31:0] -1'b1;
  else
     counter[31:0] <= counter[31:0];
end

assign pad_vic_event_vld = (counter[31:0] == 32'b0) && counter_en;


assign pmu_wic_wakeup = intraw_vld && wic_ctl_en && lpmd_en_ff ;



assign event_vld = pad_vic_event_vld && !event_ff && lpmd_en_ff ;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    event_ff <= 1'b0;
  else
    event_ff <= pad_vic_event_vld;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    event_pending <= 1'b0;
  else if (event_vld)
    event_pending <= 1'b1;
  else if (low_power_dis)
    event_pending <= 1'b0;
end

assign pmu_event_wakeup = event_pending && event_ctl_en ;



tap2_sm  x_tap2_sm (
  .debug_wake_vld      (debug_wake_vld     ),
  .pad_had_jtg_tap_en  (pad_had_jtg_tap_en ),
  .tclk                (i_pad_jtg_tclk     ),
  .tms_i               (pad_had_jtg_tms    ),
  .trst_b              (i_pad_cpu_jtg_rst_b)
);

assign debug_vld_pre = (debug_wake_vld || !had_pad_wakeup_req_b) && lpmd_en_ff;


px_had_sync  x_jtag2pmu_sync (
  .clk1                   (i_pad_jtg_tclk        ),
  .clk2                   (pmu_clk               ),
  .rst1_b                 (pad_had_jtg_trst_b_pre),
  .rst2_b                 (pad_cpu_rst_b         ),
  .sync_in                (debug_vld_pre         ),
  .sync_out               (debug_vld             )
);

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    debug_pending <= 1'b0;
  else if (debug_vld)
    debug_pending <= 1'b1;
  else if (low_power_dis)
    debug_pending <= 1'b0;
end
 
assign pad_had_jdb_req_b = !debug_pending;
assign pmu_debug_wakeup = debug_pending && debug_ctl_en ;

assign pmu_wakeup = pmu_event_wakeup || pmu_wic_wakeup || pmu_debug_wakeup ;


assign pmu_lp_mode_pwr_off       = pmu_lp_mode_sel[4];
assign pmu_lp_mode_ret_pwr_off   = pmu_lp_mode_sel[3];
assign pmu_lp_mode_clk_off       = pmu_lp_mode_sel[2];
assign pmu_lp_mode_clk_slow      = pmu_lp_mode_sel[1];
assign pmu_lp_mode_normal        = pmu_lp_mode_sel[0];



wire normal_req;


wire cpu_slp_req;
assign normal_req    = biu_pad_lpmd_b[1:0] == 2'b11;


assign cpu_slp_req   = biu_pad_lpmd_b[1:0] != 2'b11;

reg         dslp_in_sequence_req;
reg         dslp_in_sequence_done; 
reg         dslp_out_sequence_req;
reg         dslp_out_sequence_done; 
reg [15:0]  dslp_sequence_counter;
reg         dslp_sequence_counter_enable;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b)
    cur_state[2:0] <= NORMAL_MODE;
  else
    cur_state[2:0] <= next_state[2:0];
end

always @(*) begin
  case(cur_state)
  NORMAL_MODE:
    begin
      if(pmu_lp_mode_normal) 
        next_state = NORMAL_MODE;
      else if(pmu_lp_mode_clk_slow || pmu_lp_mode_clk_off)
        if(cpu_slp_req)
          next_state = LIGHT_SLP_MODE;
        else
          next_state = NORMAL_MODE;
      else if(pmu_lp_mode_ret_pwr_off || pmu_lp_mode_pwr_off)
        if(cpu_slp_req)
          next_state = DEEP_SLP_MODE;
        else
          next_state = NORMAL_MODE;
      else
        next_state = NORMAL_MODE;
    end
  LIGHT_SLP_MODE:
    begin
      if(pmu_wakeup)
        next_state = LSLP_TO_NORMAL;
      else
        next_state = LIGHT_SLP_MODE;
    end
  LSLP_TO_NORMAL:
    begin
      if(normal_req)
        next_state = NORMAL_MODE;
      else
        next_state = LSLP_TO_NORMAL;
    end
  DEEP_SLP_MODE:
    begin
      if(pmu_wakeup && dslp_in_sequence_done)
        next_state = DSLP_TO_NORMAL;
      else
        next_state = DEEP_SLP_MODE;
    end
  DSLP_TO_NORMAL:
    begin
      if(normal_req && dslp_out_sequence_done)
        next_state = NORMAL_MODE;
      else
        next_state = DSLP_TO_NORMAL;
    end
  endcase
end









assign gate_en0 = (cur_state[2:0] == LIGHT_SLP_MODE) && pmu_lp_mode_clk_slow ? 1 : 0;
assign gate_en1 = (cur_state[2:0] == LIGHT_SLP_MODE && pmu_lp_mode_clk_off) ||
                  (cur_state[2:0] == DEEP_SLP_MODE  && pmu_lp_mode_ret_pwr_off) 
                  ? 1 : 0;

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if (!pad_cpu_rst_b) begin
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b0;
  end
  else if (cur_state[2:0] == NORMAL_MODE && next_state[2:0] == DEEP_SLP_MODE) begin
    dslp_in_sequence_req    <= 1'b1;
    dslp_out_sequence_req   <= 1'b0;
  end
  else if (cur_state[2:0] == DEEP_SLP_MODE && next_state[2:0] == DSLP_TO_NORMAL) begin
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b1;
  end
  else begin 
    dslp_in_sequence_req    <= 1'b0;
    dslp_out_sequence_req   <= 1'b0;
  end
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
    dslp_sequence_counter_enable    <= 1'b0;
  else if (dslp_in_sequence_req || dslp_out_sequence_req)
    dslp_sequence_counter_enable    <= 1'b1;
  else if (dslp_in_sequence_done || dslp_out_sequence_done)
    dslp_sequence_counter_enable    <= 1'b0;
  else
    dslp_sequence_counter_enable    <= dslp_sequence_counter_enable;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
    dslp_sequence_counter[15:0]    <= 16'h0;
  else if (dslp_sequence_counter_enable)
    dslp_sequence_counter[15:0]    <= dslp_sequence_counter[15:0] + 1'b1;
  else
    dslp_sequence_counter[15:0]    <= 16'h0;
end

always @(posedge pmu_clk or negedge pad_cpu_rst_b)
begin
  if(!pad_cpu_rst_b)
  begin
    pmu_cpu_pwr_on    <= 1'b1; 
    pmu_cpu_iso_in    <= 1'b0; 
    pmu_cpu_iso_out   <= 1'b0; 
    pmu_cpu_save      <= 1'b0;
    pmu_cpu_restore   <= 1'b0;

    dslp_in_sequence_done  <= 1'b0;
    dslp_out_sequence_done <= 1'b0;
  end
  else if (cur_state[2:0] == DEEP_SLP_MODE)
  begin
    pmu_cpu_restore        <= 1'b0;
    dslp_out_sequence_done <= 1'b0;

    case(dslp_sequence_counter[15:0])
    16'h1:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h20:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h40:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b1;
      end
    16'h41:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;
      end
    16'h60:
      begin
        pmu_cpu_pwr_on     <= 1'b0; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_save       <= 1'b0;

        dslp_in_sequence_done <= 1'b1;
      end
    default:
      begin
        pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
        pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
        pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
        pmu_cpu_save       <= pmu_cpu_save   ;

        dslp_in_sequence_done <= dslp_in_sequence_done;
      end
    endcase
  end
  else if (cur_state[2:0] == DSLP_TO_NORMAL)
  begin
    pmu_cpu_save           <= 1'b0;
    dslp_in_sequence_done  <= 1'b0;

    case(dslp_sequence_counter[15:0])
    16'h1:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h20:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b1;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h21:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b1; 
        pmu_cpu_iso_out    <= 1'b1; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h40:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b0;
      end
    16'h60:
      begin
        pmu_cpu_pwr_on     <= 1'b1; 
        pmu_cpu_iso_in     <= 1'b0; 
        pmu_cpu_iso_out    <= 1'b0; 
        pmu_cpu_restore    <= 1'b0;

        dslp_out_sequence_done <= 1'b1;
      end
    default:
      begin
        pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
        pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
        pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
        pmu_cpu_restore    <= pmu_cpu_restore   ;

        dslp_out_sequence_done <= dslp_out_sequence_done;
      end
    endcase
  end
  else
  begin
    pmu_cpu_pwr_on     <= pmu_cpu_pwr_on ; 
    pmu_cpu_iso_in     <= pmu_cpu_iso_in ; 
    pmu_cpu_iso_out    <= pmu_cpu_iso_out; 
    pmu_cpu_save       <= pmu_cpu_save   ;
    pmu_cpu_restore    <= pmu_cpu_restore;

    dslp_in_sequence_done  <= dslp_in_sequence_done;
    dslp_out_sequence_done <= dslp_out_sequence_done;
  end
end



assign pg_reset_b          = pad_cpu_rst_b;
assign pad_had_jtg_trst_b  = pad_had_jtg_trst_b_pre;

endmodule