data/full_repos/permissive/447976230/fpga/usrp2/opencores/simple_pic/rtl/simple_pic.v
data/verilator_xmls/46b07b7f-d664-4dc2-86d7-336300152b44.xml
module simple_pic(
  clk_i, rst_i, cyc_i, stb_i, adr_i, we_i, dat_i, dat_o, ack_o, int_o,
  irq
);
   parameter is = 8;
   parameter dwidth = 32;





  input         clk_i;
  input         rst_i;
  input         cyc_i;
  input         stb_i;
  input  [ 2:1] adr_i;
  input         we_i;
  input  [ dwidth-1:0] dat_i;
  output [ dwidth-1:0] dat_o;
  output        ack_o;

  output        int_o;




  input  [is:1] irq;





  reg  [is:1] pol, edgen, pending, mask;
  reg  [is:1] lirq, dirq;






  initial
  begin
      if(is > dwidth)
        $display("simple_pic: max number of interrupts = data bus width.");
  end




  always @(posedge clk_i)
    lirq <= #1 irq;



  always @(posedge clk_i)
    dirq <= #1 lirq;




  function trigger;
    input edgen, pol, lirq, dirq;

    reg   edge_irq, level_irq;
  begin
      edge_irq  = pol ? (lirq & ~dirq) : (dirq & ~lirq);
      level_irq = pol ? lirq : ~lirq;

      trigger = edgen ? edge_irq : level_irq;
  end
  endfunction

  reg  [is:1] irq_event;
  integer n;
  always @(posedge clk_i)
    for(n=1; n<=is; n=n+1)
      irq_event[n] <= #1 trigger(edgen[n], pol[n], lirq[n], dirq[n]);



  wire wb_acc = cyc_i & stb_i;
  wire wb_wr  = wb_acc & we_i;

  always @(posedge clk_i)
    if (rst_i)
      begin
          pol   <= #1 {is{1'b0}};
          edgen <= #1 {is{1'b0}};
          mask  <= #1 {is{1'b1}};
      end
    else if(wb_wr)
      case (adr_i)
        2'b00: edgen <= #1 dat_i[is-1:0];
        2'b01: pol   <= #1 dat_i[is-1:0];
        2'b10: mask  <= #1 dat_i[is-1:0];
        2'b11: ;
      endcase



    always @(posedge clk_i)
      if (rst_i)
          pending <= #1 {is{1'b0}};
      else if ( wb_wr & (&adr_i) )
          pending <= #1 (pending & ~dat_i[is-1:0]) | irq_event;
      else
          pending <= #1 pending | irq_event;



    reg [dwidth-1:0] dat_o;
    always @(posedge clk_i)
      case (adr_i)
        2'b00: dat_o <= #1 { {(dwidth-is){1'b0}}, edgen};
        2'b01: dat_o <= #1 { {(dwidth-is){1'b0}}, pol};
        2'b10: dat_o <= #1 { {(dwidth-is){1'b0}}, mask};
        2'b11: dat_o <= #1 { {(dwidth-is){1'b0}}, pending};
      endcase



   reg ack_o;
   always @(posedge clk_i)
     ack_o <= #1 wb_acc & !ack_o;



  reg int_o;
  always @(posedge clk_i)
    if(rst_i)
      int_o <= #1 0;
    else
      int_o <= #1 |(pending & ~mask);

endmodule
module simple_pic(
  clk_i, rst_i, cyc_i, stb_i, adr_i, we_i, dat_i, dat_o, ack_o, int_o,
  irq
);

   parameter is = 8;
   parameter dwidth = 32;





  input         clk_i;
  input         rst_i;
  input         cyc_i;
  input         stb_i;
  input  [ 2:1] adr_i;
  input         we_i;
  input  [ dwidth-1:0] dat_i;
  output [ dwidth-1:0] dat_o;
  output        ack_o;

  output        int_o;




  input  [is:1] irq;





  reg  [is:1] pol, edgen, pending, mask;
  reg  [is:1] lirq, dirq;






  initial
  begin
      if(is > dwidth)
        $display("simple_pic: max number of interrupts = data bus width.");
  end




  always @(posedge clk_i)
    lirq <= #1 irq;



  always @(posedge clk_i)
    dirq <= #1 lirq;




  function trigger;
    input edgen, pol, lirq, dirq;

    reg   edge_irq, level_irq;
  begin
      edge_irq  = pol ? (lirq & ~dirq) : (dirq & ~lirq);
      level_irq = pol ? lirq : ~lirq;

      trigger = edgen ? edge_irq : level_irq;
  end
  endfunction

  reg  [is:1] irq_event;
  integer n;
  always @(posedge clk_i)
    for(n=1; n<=is; n=n+1)
      irq_event[n] <= #1 trigger(edgen[n], pol[n], lirq[n], dirq[n]);



  wire wb_acc = cyc_i & stb_i;
  wire wb_wr  = wb_acc & we_i;

  always @(posedge clk_i)
    if (rst_i)
      begin
          pol   <= #1 {is{1'b0}};
          edgen <= #1 {is{1'b0}};
          mask  <= #1 {is{1'b1}};
      end
    else if(wb_wr)
      case (adr_i)
        2'b00: edgen <= #1 dat_i[is-1:0];
        2'b01: pol   <= #1 dat_i[is-1:0];
        2'b10: mask  <= #1 dat_i[is-1:0];
        2'b11: ;
      endcase



    always @(posedge clk_i)
      if (rst_i)
          pending <= #1 {is{1'b0}};
      else if ( wb_wr & (&adr_i) )
          pending <= #1 (pending & ~dat_i[is-1:0]) | irq_event;
      else
          pending <= #1 pending | irq_event;



    reg [dwidth-1:0] dat_o;
    always @(posedge clk_i)
      case (adr_i)
        2'b00: dat_o <= #1 { {(dwidth-is){1'b0}}, edgen};
        2'b01: dat_o <= #1 { {(dwidth-is){1'b0}}, pol};
        2'b10: dat_o <= #1 { {(dwidth-is){1'b0}}, mask};
        2'b11: dat_o <= #1 { {(dwidth-is){1'b0}}, pending};
      endcase



   reg ack_o;
   always @(posedge clk_i)
     ack_o <= #1 wb_acc & !ack_o;



  reg int_o;
  always @(posedge clk_i)
    if(rst_i)
      int_o <= #1 0;
    else
      int_o <= #1 |(pending & ~mask);

endmodule