module counter(
  interrupt,
  pclk,
  presetn,
  timer_current_value,
  timer_enable,
  timer_load_count,
  timer_mode
);

// &Ports; @24
input           pclk;               
input           presetn;            
input           timer_enable;       
input   [31:0]  timer_load_count;   
input           timer_mode;         
output          interrupt;          
output  [31:0]  timer_current_value; 

// &Regs; @25
reg     [31:0]  counter;            
reg             interrupt;          
reg             timer_enable_flop;  

// &Wires; @26
wire            load_cnt_en;        
wire            pclk;               
wire            presetn;            
wire    [31:0]  timer_current_value; 
wire            timer_enable;       
wire    [31:0]  timer_load_count;   
wire            timer_mode;         


//==========================================================
//                 Counter
//==========================================================
always @(posedge pclk or negedge presetn)
begin
  if(!presetn)
  begin
      timer_enable_flop <=0;
  end
  else
  begin
      timer_enable_flop <=timer_enable ;
  end
end

assign load_cnt_en= (timer_enable && !timer_enable_flop)
                    || !(|counter[31:0]);

always @(posedge pclk or negedge presetn)
begin
  if(!presetn)
  begin
      counter[31:0] <=32'hffffffff;
  end
  else if(load_cnt_en)
  begin
    if(timer_mode)
    begin
      counter[31:0]<=timer_load_count[31:0];
    end
    else 
    begin
      counter[31:0]<=32'hffffffff;
    end
  end
  else if (timer_enable)
  begin
    counter[31:0]<=counter[31:0]-1'b1;
  end
  else
  begin
    counter[31:0]<=counter[31:0];
  end
end

assign timer_current_value[31:0]=counter[31:0];
//==========================================================
//                Interrupt sigals 
//==========================================================
//internel interrupt
always @(posedge pclk or negedge presetn)
begin
  if(!presetn)
  begin
    interrupt <=1'b0;
  end
  else if(!{|counter[31:0]})
  begin
    interrupt <=1'b1;
  end
  else
  begin
    interrupt<=1'b0 ;
  end
end

// &ModuleEnd; @94
endmodule