module gpio_ctrl(
  gpio_ext_porta,
  gpio_ext_porta_rb,
  gpio_int_polarity,
  gpio_inten,
  gpio_intmask,
  gpio_intr,
  gpio_intr_flag_int,
  gpio_intr_int,
  gpio_intrclk_en,
  gpio_inttype_level,
  gpio_ls_sync,
  gpio_porta_ddr,
  gpio_porta_dr,
  gpio_porta_eoi,
  gpio_raw_intstatus,
  gpio_swporta_ctl,
  gpio_swporta_ddr,
  gpio_swporta_dr,
  pclk,
  pclk_intr,
  presetn
);

// &Ports; @22
input   [7:0]  gpio_ext_porta;           
input   [7:0]  gpio_int_polarity;        
input   [7:0]  gpio_inten;               
input   [7:0]  gpio_intmask;             
input   [7:0]  gpio_inttype_level;       
input          gpio_ls_sync;             
input   [7:0]  gpio_porta_eoi;           
input   [7:0]  gpio_swporta_ctl;         
input   [7:0]  gpio_swporta_ddr;         
input   [7:0]  gpio_swporta_dr;          
input          pclk;                     
input          pclk_intr;                
input          presetn;                  
output  [7:0]  gpio_ext_porta_rb;        
output  [7:0]  gpio_intr;                
output         gpio_intr_flag_int;       
output  [7:0]  gpio_intr_int;            
output         gpio_intrclk_en;          
output  [7:0]  gpio_porta_ddr;           
output  [7:0]  gpio_porta_dr;            
output  [7:0]  gpio_raw_intstatus;       

// &Regs; @23
reg     [7:0]  ed_int_d1;                
reg     [7:0]  ed_out;                   
reg     [7:0]  gpio_ext_porta_int;       
reg     [7:0]  gpio_ext_porta_rb;        
reg     [7:0]  gpio_intr_ed_pm;          
reg            gpio_intrclk_en;          
reg     [7:0]  gpio_porta_ddr;           
reg     [7:0]  gpio_porta_dr;            
reg     [7:0]  int_gpio_raw_intstatus;   
reg     [7:0]  int_pre_in;               
reg     [7:0]  int_s1;                   
reg     [7:0]  int_sy_in;                
reg     [7:0]  intrclk_en;               
reg     [7:0]  ls_int_in;                

// &Wires; @24
wire    [7:0]  ed_rf;                    
wire    [7:0]  gpio_ext_porta;           
wire    [7:0]  gpio_int_polarity;        
wire    [7:0]  gpio_inten;               
wire    [7:0]  gpio_intmask;             
wire    [7:0]  gpio_intr;                
wire           gpio_intr_flag_int;       
wire    [7:0]  gpio_intr_int;            
wire           gpio_intrclk_en_int;      
wire    [7:0]  gpio_inttype_level;       
wire           gpio_ls_sync;             
wire    [7:0]  gpio_porta_eoi;           
wire    [7:0]  gpio_raw_intstatus;       
wire    [7:0]  gpio_swporta_ctl;         
wire    [7:0]  gpio_swporta_ctl_internal; 
wire    [7:0]  gpio_swporta_ddr;         
wire    [7:0]  gpio_swporta_dr;          
wire    [7:0]  int_in;                   
wire           pclk;                     
wire           pclk_intr;                
wire           presetn;                  


// &Force("output", "gpio_intr"); @26
// &Force("output", "gpio_intr_int"); @27
// &Force("output", "gpio_raw_intstatus"); @28
// &Force("output", "gpio_porta_ddr"); @29

// gpio_intrclk_en output asserted if any bit of port
// a is enabled for edge sensitive interrupts or
// any bit of port a is enabled for level sensitive
// interrupts and level sensitive synchronisation
// is required.
integer type_i;
// &CombBeg; @37
always @( gpio_inttype_level[1:0]
       or gpio_ls_sync
       or gpio_inten[7:0]
       or gpio_inttype_level[7:1])
begin

  for(type_i = 0 ; type_i < 8 ; type_i=type_i+1)
  begin
    if(gpio_inten[type_i] == 1'b1)
      if(gpio_inttype_level[type_i] == 1'b1)
        intrclk_en[type_i] = 1'b1;
      else
        intrclk_en[type_i] = gpio_ls_sync;
    else
      intrclk_en[type_i] = 1'b0;
  end
// &CombEnd; @49
end

assign gpio_intrclk_en_int = | intrclk_en;

always@(posedge pclk or negedge presetn)
begin
  if(!presetn)
    gpio_intrclk_en <= 1'b0;
  else
    gpio_intrclk_en <= gpio_intrclk_en_int;
end

// Input is inverted for falling edge or active low 
// sensitive interrupts.
integer polarity_i;
// &CombBeg; @64
always @( gpio_ext_porta[1:0]
       or gpio_int_polarity[7:0]
       or gpio_ext_porta[7:0]
       or gpio_int_polarity[1:0])
begin
  gpio_ext_porta_int[7:0] = {8{1'b0}};
  for(polarity_i = 0 ; polarity_i < 8 ; polarity_i=polarity_i+1)
  begin
    if(gpio_int_polarity[polarity_i] == 1'b0)
      gpio_ext_porta_int[polarity_i] =  ~gpio_ext_porta[polarity_i];
    else
      gpio_ext_porta_int[polarity_i] =  gpio_ext_porta[polarity_i];
  end
// &CombEnd; @73
end

// &CombBeg; @75
always @( gpio_ext_porta_int[7:0])
begin
  int_sy_in[7:0] = {8{1'b0}};
  int_sy_in[7:0] = gpio_ext_porta_int[7:0];
// &CombEnd; @78
end

// Meta-stabilty registers. Synchronize to pclk_intr. 
always @(posedge pclk_intr or negedge presetn)
begin
  if(!presetn)
    int_s1[7:0] <= {8{1'b0}};
  else
    int_s1[7:0] <= int_sy_in[7:0];
end

always @(posedge pclk_intr or negedge presetn)
begin 
  if(!presetn)
    int_pre_in[7:0] <= {8{1'b0}};
  else
    int_pre_in[7:0] <= int_s1;
end

assign int_in[7:0] = int_pre_in[7:0];

// edge detect circuitry.
always @(posedge pclk_intr or negedge presetn)
begin
  if(!presetn)
    ed_int_d1[7:0] <= {8{1'b0}};
  else
    ed_int_d1[7:0] <= int_in[7:0];
end

assign ed_rf[7:0] = int_in ^ ed_int_d1;

// Rising edge detect 
integer ed_j;
// &CombBeg; @112
always @( ed_rf[7:0]
       or int_in[7:0])
begin

  ed_out[7:0] = {8{1'b0}};
  for(ed_j = 0 ; ed_j < 8 ; ed_j=ed_j+1)
  begin
    ed_out[ed_j] =  ed_rf[ed_j] & int_in[ed_j];
  end
// &CombEnd; @119
end

// edge detect interrupt register pre-masking. If edge detection
// occurs at same time as write to interrupt clear register then 
// write to interrupt clear register will not clear the interrupt. 
// Interrupts can only be set when direction is input and in 
// software mode.
assign gpio_swporta_ctl_internal[7:0] = gpio_swporta_ctl[7:0];
integer int_k;
always @(posedge pclk_intr or negedge presetn)
begin
  if(!presetn)
    gpio_intr_ed_pm[7:0] <= {8{1'b0}};
  else
    for(int_k = 0 ; int_k < 8 ; int_k=int_k+1)
    begin
      if(gpio_inten[int_k] == 1'b0)
        gpio_intr_ed_pm[int_k] <= 1'b0;
      else
        if((ed_out[int_k] == 1'b1) &&
           (gpio_inten[int_k] == 1'b1) &&
           (gpio_swporta_ddr[int_k] == 1'b0) &&
           (gpio_swporta_ctl_internal[int_k] == 1'b0))
          gpio_intr_ed_pm[int_k] <= 1'b1;
      else
        if(gpio_porta_eoi[int_k] == 1'b1)
          gpio_intr_ed_pm[int_k] <= 1'b0;
    end
end

// Level senistive interrupts may pass through synchronization 
// and debounce logic. Under S/W control.
// Interrupts can only be set when direction is input and in
// software mode.
integer lsa_k;

// &CombBeg; @155
always @( int_in[7:0]
       or gpio_swporta_ddr[7:0]
       or gpio_swporta_ctl_internal[2:0]
       or gpio_ls_sync
       or int_sy_in[7:0]
       or gpio_swporta_ctl_internal[7:2])
begin
  ls_int_in[7:0] = {8{1'b0}};
  for(lsa_k = 0 ; lsa_k < 8 ; lsa_k=lsa_k+1)
  begin
    if(((gpio_swporta_ddr[lsa_k]) == 1'b1) ||  
        (gpio_swporta_ctl_internal[lsa_k] == 1'b1))
      ls_int_in[lsa_k] = 0;
    else
      if(gpio_ls_sync == 1'b1)
        ls_int_in[lsa_k] = int_in[lsa_k];
      else
        ls_int_in[lsa_k] = int_sy_in[lsa_k];
  end
// &CombEnd; @168
end

// Level or edge sensitive interrupts 
integer raw_l;

// &CombBeg; @173
always @( gpio_inten[7:3]
       or gpio_intr_ed_pm[2:0]
       or gpio_intr_ed_pm[7:1]
       or gpio_inten[4:0]
       or gpio_inttype_level[7:0]
       or ls_int_in[7:0])
begin
  int_gpio_raw_intstatus[7:0] = {8{1'b0}};
  for(raw_l = 0 ; raw_l < 8 ; raw_l=raw_l+1)
  begin
    if(gpio_inten[raw_l] == 1'b0)
      int_gpio_raw_intstatus[raw_l] = 0;
    else
      if(gpio_inttype_level[raw_l] == 1'b1)
        int_gpio_raw_intstatus[raw_l] = gpio_intr_ed_pm[raw_l];
      else
        int_gpio_raw_intstatus[raw_l] = ls_int_in[raw_l];
  end
// &CombEnd; @185
end

assign gpio_raw_intstatus[7:0] = int_gpio_raw_intstatus[7:0];
assign gpio_intr_int[7:0] = gpio_raw_intstatus[7:0] & ~gpio_intmask[7:0]; 
assign gpio_intr[7:0] = gpio_intr_int[7:0];

assign gpio_intr_flag_int = |gpio_intr_int[7:0];
// &CombBeg; @192
always @( gpio_swporta_dr[7:0])
begin
  gpio_porta_dr[7:0] = {8{1'b0}};
  gpio_porta_dr[7:0] = gpio_swporta_dr[7:0];
// &CombEnd; @195
end

// &CombBeg; @197
always @( gpio_swporta_ddr[7:0])
begin
  gpio_porta_ddr[7:0] = {8{1'b0}};
  gpio_porta_ddr[7:0] = gpio_swporta_ddr[7:0];
// &CombEnd; @200
end

integer rba_i;

// &CombBeg; @204
always @( gpio_swporta_dr[2:1]
       or gpio_ext_porta[7:0]
       or gpio_swporta_dr[7:0]
       or gpio_porta_ddr[7:0])
begin
  gpio_ext_porta_rb[7:0] = {8{1'b0}};
  for(rba_i = 0 ; rba_i < 8 ; rba_i=rba_i+1)
  begin
    if(gpio_porta_ddr[rba_i] == 1'b1)
      gpio_ext_porta_rb[rba_i] = gpio_swporta_dr[rba_i];
    else
      gpio_ext_porta_rb[rba_i] = gpio_ext_porta[rba_i];
  end
// &CombEnd; @213
end

integer rbb_i;

// &ModuleEnd; @217
endmodule