dakies/OSS_Verilog huggingface dataset:
module top (SW, KEY, LEDR);

    input wire [9:0] SW;        // DE-series switches
    input wire [3:0] KEY;       // DE-series pushbuttons

    output wire [9:0] LEDR;     // DE-series LEDs   

    cnt_load lab6 (KEY[0], KEY[1], KEY[2], SW, LEDR);
 
endmodule
module testbench;

   localparam NEW_WIDTH = 16;
   
   reg                  clk;
   reg                  rst_n;
   reg                  load;
   reg [NEW_WIDTH-1:0]  data_load;
   wire [NEW_WIDTH-1:0] cnt;
   integer              i;
   integer              pre_delay;
   integer              load_width;
   
   cnt_load #(.WIDTH(NEW_WIDTH))
   cnt_dut (
            .clk       ( clk       ),
            .rst_n     ( rst_n     ),
            .load      ( load      ),
            .data_load ( data_load ),
            .cnt       ( cnt       )
      );
   
   // Clock generator
   initial begin
      clk=0;
      forever #10 clk=!clk;
   end
   
 // Set reset duration
   task reset(input integer unsigned rst_time);
      begin
         $display("########## Reset start ##########");
         rst_n  = 1'b0;
         #(rst_time) rst_n =1'b1;
         $display("########## Reset finish ##########\n");
      end
   endtask // reset

   // Set random data for load
   task set_data;
      begin
         $display("########## Set load_data ##########");
         pre_delay       = $urandom%(30);
         load_width        = $urandom%(50)+10;
         data_load       = $urandom%(2**NEW_WIDTH-1);
         #(pre_delay) load   = 1'b1;
         #(load_width) load  = 1'b0;
         $display("########## Finish load data ##########\n");
      end   
   endtask // set_data
   
   initial begin
      //For Icarus simulation
      $dumpvars();
      
      $monitor("@time=%0t\t load=%0b\t data_load=0x%h\t cnt=0x%h",$time,load,data_load,cnt);
      //Initial value at 0 time
      rst_n    = 1'b1;
      load   = 1'b0;
      data_load  = 0;

      //Reset design
      #14 reset(24);

      // Generate load_data
      for(i=0;i<10;i=i+1)begin
         #80 set_data();
      end
      #100 $finish;
            
   end
endmodule // testbench
module top (SW, KEY, LEDR);

    input wire [9:0] SW;        // DE-series switches
    input wire [3:0] KEY;       // DE-series pushbuttons

    output wire [9:0] LEDR;     // DE-series LEDs   

    shift_reg lab6 (KEY[0], SW[0], KEY[2], KEY[3], LEDR[7:0], LEDR[9]);
 
endmodule
module testbench;

   localparam WIDTH=8;
   
   reg        clk;
   reg        rst_n;
   reg        shift_en;
   reg        data_in;
   wire [7:0] data_out;
   wire       serial_out;
      
   
   shift_reg #(.WIDTH(WIDTH)) shft
   (// Outputs
      .data_out   ( data_out   ),
      .serial_out ( serial_out ),
      // Inputs
      .clk        ( clk        ),
      .rst_n      ( rst_n      ),
      .data_in    ( data_in    ),
      .shift_en   ( shift_en   )
   );

   //Clock generation
   initial begin
      clk = 0;
      forever #4 clk = ~clk;
   end

   // Create serial package
   task push;
      begin
         $display("########## Shift enable active ##########");
         shift_en  = 1'b1;
         repeat(9)begin
            @(negedge clk)
              data_in = $urandom%2;
         end
         shift_en  = 1'b0;
         $display("########## Shift enable disable ##########\n");
      end
   endtask

   // Create reset signal
   task async_rst;
      begin
         $display("########## RESET start! ##########");
         #10 rst_n = 1'b0;
         #10 rst_n = 1'b1;
         $display("########## RESET finish!\n ##########");
      end
   endtask
   
   initial begin
      $dumpvars();
      $display("#################### Starting simulation ####################");
      $monitor("@time=%0t\t data_out=0x%h\t",$time,data_out);
      
      shift_en  = 1'b0;
      rst_n     = 1'b1;
      data_in   = 1'b0;
      
      //Async reset
      async_rst();
      
     //Push new data
      repeat(10) begin
         #50 push;
      end      
      #200 $finish;
   end
   
endmodule // testbench
module top (SW, KEY, LEDR);

    input wire [9:0] SW;        // DE-series switches
    input wire [3:0] KEY;       // DE-series pushbuttons

    output wire [9:0] LEDR;     // DE-series LEDs   

    pwm lab6 (KEY[0], KEY[2], SW, LEDR);
 
endmodule
module testbench;
   
   localparam PWM_SIZE=8;
   
   reg                clk;
   reg                rst_n;
   reg [PWM_SIZE-1:0] imp_width;
   wire               pwm_out;
   // Quantity of data
   integer            i;
   //random number of pulses
   integer            cycle_cnt;
   
   pwm #(.PWM_WIDTH(PWM_SIZE))
   pwm_inst
     (
      .clk      ( clk       ),
      .rst_n    ( rst_n     ),
      .imp_width( imp_width ),
      .pwm_out  ( pwm_out   )
      );
   
   //Clock generation
   initial begin
      clk = 1'b0;
      forever #2 clk = ~clk;
   end

   task async_rst;
      begin
         $display("---------- Reset start at %0t ns -----------",$time);
         #23 rst_n = 1'b0;
         #15 rst_n = 1'b1;
         $display("---------- Reset finish at %0t ns ---------\n",$time); 
      end
   endtask // async_rst
   
   //Create random input data
   task in_data(input integer imp_cnt);
      begin
         imp_width=$urandom%(2**PWM_SIZE-1);
         repeat(imp_cnt+1)
           @(posedge pwm_out);
      end
   endtask // in_data
   
   
   initial begin
      $dumpvars();
      
      imp_width  = 8'h0;
      rst_n      = 1'b1;
      
      //Async reset
      async_rst;
      
      //Start simulation

      for(i=0;i<10;i=i+1)
        begin
           cycle_cnt = $urandom%(10);
           #10 in_data(cycle_cnt);
        end
      #100 $finish;
   end 
   
endmodule // testbench
module top (SW, KEY, LEDR);

    input wire [9:0] SW;        // DE-series switches
    input wire [3:0] KEY;       // DE-series pushbuttons

    output wire [9:0] LEDR;     // DE-series LEDs   

    hcsr04 lab6 (KEY[0], SW[0], KEY[2], LEDR[9], LEDR[7:0]);
 
endmodule
module de10_lite
(
 input        CLOCK_50,
 input [0:0]  KEY,
 output [7:0] HEX1,
 output [7:0] HEX0,
 inout [35:0] GPIO
);
  localparam width=8;
  
  wire             key_rst;
  wire             trig_pin;
  wire             echo_pin;
  wire [width-1:0] distance;
  
 
  assign key_rst  = KEY[0];
  assign GPIO[35] = trig_pin;
  assign echo_pin = GPIO[33];
  
  hcsr04
   #(
     .clk_freq ( 50000000 ),
     .width    ( width    )
    )
  hc
    (
     .clk      ( CLOCK_50 ),
     .rst_n    ( key_rst  ),
     .echo     ( echo_pin ),
     .trig     ( trig_pin ),
     .distance ( distance )
    );
    
  led7 #(.COUNT(2)) seg7
    (
     .data ( distance    ),
     .leds ( {HEX1,HEX0} )
    );
  
  
endmodule // de10_lite
module testbench;

  localparam CLK_FREQ = 500000,
                WIDTH = 8;
  
  reg        clk;
  reg        rst_n;
  reg        echo;
  wire       trig;
  wire [7:0] distance;
  
  hcsr04
   #(
     .clk_freq ( CLK_FREQ ),
     .width    ( WIDTH    )
    )
  hc_dut
    (
     .clk      ( clk      ),
     .rst_n    ( rst_n    ),
     .echo     ( echo     ),
     .trig     ( trig     ),
     .distance ( distance )
    );

  initial begin
    clk = 1'b0;
    forever
      #10 clk = !clk;
  end

  task request(input integer del,input integer dur);
    // int del,dur
    @(negedge trig) begin
      #(del) echo = 1'b1;
      #(dur) echo = 1'b0;
    end
  endtask // request
  

  initial begin
    $dumpvars();
    
    rst_n     = 1'b1;
    echo      = 1'b0;

    #14 rst_n = 1'b0;
    #12 rst_n = 1'b1;
    request(9000,5000);
    request(4000,8888);
    
    #30000
    
    $finish;
    
  end
endmodule // testbench
module top (SW, KEY, LEDR);

    input wire [9:0] SW;        // DE-series switches
    input wire [3:0] KEY;       // DE-series pushbuttons

    output wire [9:0] LEDR;     // DE-series LEDs   

    crc32 lab6 (KEY[0], SW[0], SW[9:2], KEY[2], LEDR);
 
endmodule
module testbench;

  reg [7:0]   data;
  reg         clk;
  reg         rst_n;
  reg         crc_en;
  wire [31:0] crc32;
  

  crc32 crc_dut
    (
     .crc32  ( crc32[31:0]),
     .clk    ( clk        ),
     .rst_n  ( rst_n      ),
     .data   ( data[7:0]  ),
     .crc_en ( crc_en     )
   );

  initial begin
    clk = 1'b0;
    forever #5 clk = !clk;
  end
  integer    i;
  
  reg [31:0] crc_out;
  reg [63:0] crc_buff;
  reg        crc_err;
  reg [31:0] rnd_data;
  
  
  task send_int(input [31:0] d_in);
    begin
      for(i=4;i>0;i=i-1)begin
        @(negedge clk)begin
          crc_en  = 1'b1;
          data    = d_in[i*8-1-:8];
        end
      end
      @(negedge clk)begin
        crc_en = 1'b0;
        crc_out = crc32;
      end
    end
  endtask // send_data

  task check_crc(input [31:0] pack,input [31:0] crc);
    begin
      for(i=8;i>0;i=i-1)begin
        @(negedge clk)begin
          crc_en  = 1'b1;
          data    = {pack,crc} >> (8*(i-1));
        end
      end
      @(negedge clk)
        crc_en = 1'b0;
      if( crc32 != 32'h0000 ) begin
        $display("Error in current CRC value");
        crc_err = 1'b1;
      end
      else
        crc_err = 1'b0;
    end
  endtask // check_crc
  
  
  
  task async_rst;
    begin
      #11 rst_n = 1'b0;
      #11 rst_n = 1'b1;
    end
  endtask // async_rst
  
  
  initial begin
    $dumpvars();
    
    data     = 32'h00000000;
    rst_n    = 1'b1;
    crc_en   = 1'b0;
    crc_err  = 1'b0;
    crc_out  = 32'h0000;
    
  
    
    repeat(10)begin
      async_rst();
      rnd_data = $urandom;
      send_int(rnd_data);
      async_rst();
      check_crc(rnd_data,crc_out);
      
    end
  #30
    $finish;
  end

endmodule // testbench
module tb();

    reg CLOCK_50 = 0;               // DE-series 50 MHz clock
    reg [9:0] SW = 0;               // DE-series SW switches
    reg [3:0] KEY = 0;              // DE-series pushbutton keys
    wire [(8*6) -1:0] HEX;          // HEX displays (six ports)
    wire [9:0] LEDR;                // DE-series LEDs

    reg key_action = 0;
    reg [7:0] scan_code = 0;
    wire [2:0] ps2_lock_control;

    wire [7:0] VGA_X;               // "VGA" column
    wire [6:0] VGA_Y;               // "VGA" row
    wire [2:0] VGA_COLOR;           // "VGA pixel" colour (0-7)
    wire plot;                      // "Pixel" is drawn when this is pulsed
    wire [31:0] GPIO;               // DE-series GPIO port

    initial $sim_fpga(CLOCK_50, SW, KEY, LEDR, HEX, key_action, scan_code, 
                      ps2_lock_control, VGA_X, VGA_Y, VGA_COLOR, plot, GPIO);

    wire [6:0] HEX0;                // DE-series HEX0 port
    wire [6:0] HEX1;                // DE-series HEX1 port
    wire [6:0] HEX2;                // ...
    wire [6:0] HEX3;
    wire [6:0] HEX4;
    wire [6:0] HEX5;

    // create the 50 MHz clock signal
    always #10
        CLOCK_50 <= ~CLOCK_50;

    // connect the single HEX port on "sim_fpga" to the six DE-series HEX ports
    assign HEX[47:40] = {1'b0, HEX0};
    assign HEX[39:32] = {1'b0, HEX1};
    assign HEX[31:24] = {1'b0, HEX2};
    assign HEX[23:16] = {1'b0, HEX3};
    assign HEX[15: 8] = {1'b0, HEX4};
    assign HEX[ 7: 0] = {1'b0, HEX5};
    
    top DUT (.CLOCK_50(CLOCK_50), .KEY(KEY), .GPIO(GPIO));

endmodule
module shift_reg
#(
  parameter WIDTH=8
)
(
 input                  clk,
 input                  rst_n,
 input                  data_in,
 input                  shift_en,
 
 output reg [WIDTH-1:0] data_out,
 output                 serial_out      
 );

      
   always@(posedge clk or negedge rst_n)
     begin
        if(!rst_n)
          data_out <= {WIDTH{1'b0}};
        else if(shift_en)
          data_out <= {data_in,data_out[WIDTH-1:1]};
     end
   
   assign serial_out = data_out[0];
   
endmodule
module top (CLOCK_50, KEY, GPIO);

    input CLOCK_50;        // DE-series switches
    input wire [1:0] KEY;       // DE-series pushbuttons

    inout wire [31:0] GPIO;     // DE-series LEDs   

    de10_lite lab6 (CLOCK_50, KEY[1:0], GPIO);
 
endmodule
module de10_lite 
(
 input        CLOCK_50,
 input [1:0]  KEY,
 inout [35:0] GPIO 
);

  reg [15:0]  matrix;
  wire [7:0]  rows,cols;
  wire        push_button;
  wire        shift_cols;
  wire        shift_rows;
   
  assign push_button = ~KEY[1];
   
  always@(posedge CLOCK_50)
    matrix = {
              ~rows[0],~rows[1], cols[1],~rows[7],
               cols[3],~rows[2], cols[0],~rows[4],
               cols[4], cols[6],~rows[6],~rows[5],
               cols[7],~rows[3], cols[5], cols[2]
             };
   
  assign {
          GPIO[24],GPIO[22],GPIO[20],GPIO[18],
          GPIO[16],GPIO[14],GPIO[12],GPIO[10],
          GPIO[25],GPIO[23],GPIO[21],GPIO[19],
          GPIO[17],GPIO[15],GPIO[13],GPIO[11]
         } = matrix;
   
  strobe_gen #(.div(24)) strobe_rows
    (
     .clk    ( CLOCK_50      ),
     .rst_n  ( KEY[0]        ),
     .strobe ( shift_rows    )
    );
   
  strobe_gen #(.div(24)) strobe_cols
    (
     .clk    ( CLOCK_50      ),
     .rst_n  ( KEY[0]        ),
     .strobe ( shift_cols    )
    );

  shift_reg #(.WIDTH(8)) s_rows
    (
     .clk      ( CLOCK_50      ),
     .rst_n    ( KEY[0]        ),
     .data_in  ( push_button   ),
     .shift_en ( shift_rows    ),
     .data_out ( rows          ),
     .serial_out ()
    );
   
  shift_reg #(.WIDTH(8)) s_cols
    (
     .clk      ( CLOCK_50      ),
     .rst_n    ( KEY[0]        ),
     .data_in  ( push_button   ),
     .shift_en ( shift_cols    ),
     .data_out ( cols          ),
     .serial_out()
    );   

endmodule // de10_lite
module pow_5_en_single_cycle_struct
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            clk_en,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    wire           arg_vld_q;
    wire [w - 1:0] arg_q;

    reg_rst_n_en        i_arg_vld (clk, rst_n, clk_en, arg_vld, arg_vld_q);
    reg_no_rst_en # (w) i_arg     (clk, clk_en, arg, arg_q);

    wire           res_vld_d = arg_vld_q;
    wire [w - 1:0] res_d     = arg_q * arg_q * arg_q * arg_q * arg_q;

    reg_rst_n_en        i_res_vld (clk, rst_n, clk_en, res_vld_d, res_vld);
    reg_no_rst_en # (w) i_res     (clk, clk_en, res_d, res);

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_en_single_cycle_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_multi_cycle_always
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    reg           arg_vld_q;
    reg [w - 1:0] arg_q;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            arg_vld_q <= 1'b0;
        else
            arg_vld_q <= arg_vld;
    
    always @ (posedge clk)
        if (arg_vld)
            arg_q <= arg;

    reg [3:0] shift;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            shift <= 4'b0;
        else if (arg_vld_q)
            shift <= 4'b1000;
        else
            shift <= shift >> 1;

    assign res_vld = shift [0];

    reg  [w - 1:0] mul_q;
    wire [w - 1:0] mul_d = (arg_vld_q ? arg_q : mul_q) * arg_q;

    // TODO: reduce switching

    always @(posedge clk)
        if (arg_vld_q || shift [3:1] != 3'b0)
            mul_q <= mul_d;

    assign res = mul_q;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_multi_cycle_always
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk    ),
        .rst_n   ( rst_n       ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_en_pipe_always
# (
    parameter w = 8
)
(
    input                clk,
    input                rst_n,
    input                clk_en,
    input                arg_vld,
    input  [    w - 1:0] arg,
    output [        4:0] res_vld,
    output [5 * w - 1:0] res
);

    reg [w - 1:0] arg1, arg2, arg3, arg4;
    reg [w - 1:0] pow2, pow3, pow4, pow5;
    reg arg_vld_1, arg_vld_2, arg_vld_3, arg_vld_4, arg_vld_5;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
        begin
            arg_vld_1 <= 1'b0;
            arg_vld_2 <= 1'b0;
            arg_vld_3 <= 1'b0;
            arg_vld_4 <= 1'b0;
            arg_vld_5 <= 1'b0;
        end
        else if (clk_en)
        begin
            arg_vld_1 <= arg_vld;
            arg_vld_2 <= arg_vld_1;
            arg_vld_3 <= arg_vld_2;
            arg_vld_4 <= arg_vld_3;
            arg_vld_5 <= arg_vld_4;
        end

    always @ (posedge clk)
        if (clk_en)
        begin
            arg1 <= arg;
            arg2 <= arg1;
            arg3 <= arg2;
            arg4 <= arg3;

            pow2 <= arg1 * arg1;
            pow3 <= pow2 * arg2;
            pow4 <= pow3 * arg3;
            pow5 <= pow4 * arg4;
        end

    assign res_vld = { arg_vld_1 , arg_vld_2 , arg_vld_3 , arg_vld_4 , arg_vld_5 };
    assign res     = { arg1      , pow2      , pow3      , pow4      , pow5      };

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_5_en_pipe_always
    # (.w (8))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( res         )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_5_single_cycle_struct
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    wire             arg_vld_q;
    wire   [w - 1:0] arg_q;

    reg_rst_n        i_arg_vld (clk, rst_n, arg_vld, arg_vld_q);
    reg_no_rst # (w) i_arg     (clk, arg, arg_q);

    wire             res_vld_d = arg_vld_q;
    wire   [w - 1:0] res_d     = arg_q * arg_q * arg_q * arg_q * arg_q;

    reg_rst_n        i_res_vld (clk, rst_n, res_vld_d, res_vld);
    reg_no_rst # (w) i_res     (clk, res_d, res);

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_single_cycle_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk    ),
        .rst_n   ( rst_n       ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_n_en_pipe_struct
# (
    parameter w = 8, n = 5
)
(
    input                  clk,
    input                  rst_n,
    input                  clk_en,
    input                  arg_vld,
    input  [     w - 1:0 ] arg,
    output [ n     - 1:0 ] res_vld,
    output [ n * w - 1:0 ] res
);

    wire [w - 1:0] mul_d     [ 1 : n - 1     ];

    wire           arg_vld_q [ 0 : n ];
    wire [w - 1:0] arg_q     [ 0 : n ];
    wire [w - 1:0] mul_q     [ 2 : n ];

    assign arg_vld_q [0] = arg_vld;
    assign arg_q     [0] = arg;
    
    assign mul_d     [1] = arg_q [1] * arg_q [1];

    generate
    
        genvar i;
    
        for (i = 2; i <= n - 1; i = i + 1)
        begin : b_mul
            assign mul_d [i] = mul_q [i] * arg_q [i];
        end

        for (i = 1; i <= n - 1; i = i + 1)
        begin : b_mul_reg
            reg_no_rst_en # (w) i_mul
                (clk, clk_en, mul_d [i], mul_q [i + 1]);
        end

        for (i = 0; i <= n - 1; i = i + 1)
        begin : b_regs
            reg_rst_n_en i_arg_vld
                (clk, rst_n, clk_en, arg_vld_q [i], arg_vld_q [i + 1]);

            reg_no_rst_en # (w) i_arg
                (clk, clk_en, arg_q [i], arg_q [i + 1]);
        end
        
        for (i = 2; i <= n; i = i + 1)
        begin : b_res
            assign res_vld [   n - i            ] = arg_vld_q [i];
            assign res     [ ( n - i ) * w +: w ] = mul_q     [i];
        end
    
    endgenerate

    assign res_vld [   n - 1            ] = arg_vld_q [1];
    assign res     [ ( n - 1 ) * w +: w ] = arg_q     [1];

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_n_en_pipe_struct
    # (.w (8), .n (5))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( res         )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_5_en_pipe_struct
# (
    parameter w = 8
)
(
    input                clk,
    input                rst_n,
    input                clk_en,
    input                arg_vld,
    input  [    w - 1:0] arg,
    output [        4:0] res_vld,
    output [5 * w - 1:0] res
);

    wire           arg_vld_q_1;
    wire [w - 1:0] arg_q_1;

    reg_rst_n_en        i0_arg_vld (clk, rst_n, clk_en, arg_vld, arg_vld_q_1);
    reg_no_rst_en # (w) i0_arg     (clk, clk_en, arg, arg_q_1);

    assign res_vld [4         ] = arg_vld_q_1;
    assign res     [4 * w +: w] = arg_q_1;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_1 = arg_q_1 * arg_q_1;

    wire           arg_vld_q_2;
    wire [w - 1:0] arg_q_2;
    wire [w - 1:0] mul_q_2;

    reg_rst_n_en        i1_arg_vld ( clk , rst_n , clk_en , arg_vld_q_1 , arg_vld_q_2 );
    reg_no_rst_en # (w) i1_arg     ( clk ,         clk_en , arg_q_1     , arg_q_2     );
    reg_no_rst_en # (w) i1_mul     ( clk ,         clk_en , mul_d_1     , mul_q_2     );

    assign res_vld [3         ] = arg_vld_q_2;
    assign res     [3 * w +: w] = mul_q_2;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_2 = mul_q_2 * arg_q_2;

    wire           arg_vld_q_3;
    wire [w - 1:0] arg_q_3;
    wire [w - 1:0] mul_q_3;

    reg_rst_n_en        i2_arg_vld ( clk , rst_n , clk_en , arg_vld_q_2 , arg_vld_q_3 );
    reg_no_rst_en # (w) i2_arg     ( clk ,         clk_en , arg_q_2     , arg_q_3     );
    reg_no_rst_en # (w) i2_mul     ( clk ,         clk_en , mul_d_2     , mul_q_3     );

    assign res_vld [2         ] = arg_vld_q_3;
    assign res     [2 * w +: w] = mul_q_3;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_3 = mul_q_3 * arg_q_3;

    wire           arg_vld_q_4;
    wire [w - 1:0] arg_q_4;
    wire [w - 1:0] mul_q_4;

    reg_rst_n_en        i3_arg_vld ( clk , rst_n , clk_en , arg_vld_q_3 , arg_vld_q_4 );
    reg_no_rst_en # (w) i3_arg     ( clk ,         clk_en , arg_q_3     , arg_q_4     );
    reg_no_rst_en # (w) i3_mul     ( clk ,         clk_en , mul_d_3     , mul_q_4     );

    assign res_vld [1         ] = arg_vld_q_4;
    assign res     [1 * w +: w] = mul_q_4;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_4 = mul_q_4 * arg_q_4;

    wire           arg_vld_q_5;
    wire [w - 1:0] arg_q_5;
    wire [w - 1:0] mul_q_5;

    reg_rst_n_en        i4_arg_vld ( clk , rst_n , clk_en , arg_vld_q_4 , arg_vld_q_5 );
    reg_no_rst_en # (w) i4_arg     ( clk ,         clk_en , arg_q_4     , arg_q_5     );
    reg_no_rst_en # (w) i4_mul     ( clk ,         clk_en , mul_d_4     , mul_q_5     );

    assign res_vld [0         ] = arg_vld_q_5;
    assign res     [0 * w +: w] = mul_q_5;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_5_en_pipe_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( res         )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_5_single_cycle_always
# (
    parameter w = 8
)
(
    input                clk,
    input                rst_n,
    input                arg_vld,
    input      [w - 1:0] arg,
    output reg           res_vld,
    output reg [w - 1:0] res
);

    reg           arg_vld_q;
    reg [w - 1:0] arg_q;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            arg_vld_q <= 1'b0;
        else
            arg_vld_q <= arg_vld;
    
    always @ (posedge clk)
        arg_q <= arg;

    wire           res_vld_d = arg_vld_q;
    wire [w - 1:0] res_d     = arg_q  * arg_q * arg_q * arg_q * arg_q;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            res_vld <= 1'b0;
        else
            res_vld <= res_vld_d;

    always @ (posedge clk)
        res <= res_d;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_single_cycle_always
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk    ),
        .rst_n   ( rst_n       ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_multi_cycle_struct
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    wire             arg_vld_q;
    wire   [w - 1:0] arg_q;

    reg_rst_n           i_arg_vld (clk, rst_n, arg_vld, arg_vld_q);
    reg_no_rst_en # (w) i_arg     (clk, arg_vld, arg, arg_q);

    wire [3:0] shift_q;
    wire [3:0] shift_d = arg_vld_q ? 4'b1000 : shift_q >> 1;
   
    reg_rst_n # (4) i_shift (clk, rst_n, shift_d, shift_q);
    
    assign res_vld = shift_q [0];

    wire [w - 1:0] mul_q;
    wire [w - 1:0] mul_d = (arg_vld_q ? arg_q : mul_q) * arg_q;

    wire mul_en = arg_vld_q || shift_q [3:1] != 3'b0;

    reg_no_rst_en # (w) i_mul (clk, mul_en, mul_d, mul_q);
    
    assign res = mul_q;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_multi_cycle_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk    ),
        .rst_n   ( rst_n       ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_pipe_always_with_array
# (
    parameter w = 8
)
(
    input                    clk,
    input                    rst_n,
    input                    arg_vld,
    input      [    w - 1:0] arg,
    output reg [        4:0] res_vld,
    output reg [5 * w - 1:0] res
);

    reg [w - 1:0] arg_reg [1:4];
    reg [w - 1:0] pow     [2:5];
    reg [    1:5] arg_vld_reg;

    integer i;

    always @ (posedge clk or negedge rst_n)

        if (! rst_n)
        begin
            for (i = 1; i <= 5; i = i + 1)
                arg_vld_reg [i] <= 1'b0;
        end
        else
        begin
            arg_vld_reg [1] <= arg_vld;

            for (i = 1; i <= 4; i = i + 1)
                arg_vld_reg [i + 1] <= arg_vld_reg [i];
        end

    always @ (posedge clk)
    begin
        arg_reg [1] <= arg;

        for (i = 1; i <= 3; i = i + 1)
            arg_reg [i + 1] <= arg_reg [i];

        pow [2] <= arg_reg [1] * arg_reg [1];

        for (i = 2; i <= 4; i = i + 1)
            pow [i + 1] <= pow [i] * arg_reg [i];
    end

    always @*
    begin
        for (i = 1; i <= 5; i = i + 1)
            res_vld [5 - i] = arg_vld_reg [i];

        res [(5 - 1) * w +: w] = arg_reg [1];

        for (i = 2; i <= 5; i = i + 1)
            res [(5 - i) * w +: w] = pow [i];
    end

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_5_pipe_always_with_array
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk ),
        .rst_n   ( rst_n    ),
        .arg_vld ( key [0]  ),
        .arg     ( sw       ),
        .res_vld ( res_vld  ),
        .res     ( res      )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_n_pipe_struct
# (
    parameter w = 8, n = 5
)
(
    input                  clk,
    input                  rst_n,
    input                  arg_vld,
    input  [     w - 1:0 ] arg,
    output [ n     - 1:0 ] res_vld,
    output [ n * w - 1:0 ] res
);

    wire [w - 1:0] mul_d     [ 1 : n - 1 ];

    wire           arg_vld_q [ 0 : n     ];
    wire [w - 1:0] arg_q     [ 0 : n     ];
    wire [w - 1:0] mul_q     [ 2 : n     ];

    assign arg_vld_q [0] = arg_vld;
    assign arg_q     [0] = arg;
    
    assign mul_d     [1] = arg_q [1] * arg_q [1];

    generate
    
        genvar i;
    
        for (i = 2; i <= n - 1; i = i + 1)
        begin : b_mul
            assign mul_d [i] = mul_q [i] * arg_q [i];
        end

        for (i = 1; i <= n - 1; i = i + 1)
        begin : b_mul_reg
            reg_no_rst # (w) i_mul
                (clk, mul_d [i], mul_q [i + 1]);
        end

        for (i = 0; i <= n - 1; i = i + 1)
        begin : b_regs
            reg_rst_n i_arg_vld
                (clk, rst_n, arg_vld_q [i], arg_vld_q [i + 1]);

            reg_no_rst # (w) i_arg
                (clk, arg_q [i], arg_q [i + 1]);
        end
        
        for (i = 2; i <= n; i = i + 1)
        begin : b_res
            assign res_vld [   n - i            ] = arg_vld_q [i];
            assign res     [ ( n - i ) * w +: w ] = mul_q     [i];
        end
    
    endgenerate

    assign res_vld [   n - 1            ] = arg_vld_q [1];
    assign res     [ ( n - 1 ) * w +: w ] = arg_q     [1];

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_n_pipe_struct
    # (.w (8), .n (5))
    i_pow_5
    (
        .clk     ( slow_clk ),
        .rst_n   ( rst_n    ),
        .arg_vld ( key [0]  ),
        .arg     ( sw       ),
        .res_vld ( res_vld  ),
        .res     ( res      )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module reg_rst_n_en
# (
    parameter w = 1
) 
(
    input                clk,
    input                rst_n,
    input                en,
    input      [w - 1:0] d,
    output reg [w - 1:0] q
);

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            q <= { w { 1'b0 } };
        else if (en)
            q <= d;

endmodule
module reg_no_rst_en
# (
    parameter w = 1
) 
(
    input                clk,
    input                en,
    input      [w - 1:0] d,
    output reg [w - 1:0] q
);

    always @ (posedge clk)
        if (en)
            q <= d;

endmodule
module reg_rst_n
# (
    parameter w = 1
) 
(
    input                clk,
    input                rst_n,
    input      [w - 1:0] d,
    output reg [w - 1:0] q
);

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            q <= { w { 1'b0 } };
        else
            q <= d;

endmodule
module reg_no_rst
# (
    parameter w = 1
) 
(
    input                clk,
    input      [w - 1:0] d,
    output reg [w - 1:0] q
);

    always @ (posedge clk)
        q <= d;

endmodule
module pow_5_en_multi_cycle_struct
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            clk_en,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    wire           arg_vld_q;
    wire [w - 1:0] arg_q;

    reg_rst_n_en        i_arg_vld (clk, rst_n, clk_en, arg_vld, arg_vld_q);
    reg_no_rst_en # (w) i_arg     (clk, clk_en & arg_vld, arg, arg_q);

    wire [3:0] shift_q;
    wire [3:0] shift_d = arg_vld_q ? 4'b1000 : shift_q >> 1;
   
    reg_rst_n_en # (4) i_shift (clk, rst_n, clk_en, shift_d, shift_q);
    
    assign res_vld = shift_q [0];

    wire [w - 1:0] mul_q;
    wire [w - 1:0] mul_d = (arg_vld_q ? arg_q : mul_q) * arg_q;

    wire mul_en = clk_en && (arg_vld_q || shift_q [3:1] != 3'b0);

    reg_no_rst_en # (w) i_mul (clk, mul_en, mul_d, mul_q);
    
    assign res = mul_q;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_en_multi_cycle_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_en_multi_cycle_always
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            clk_en,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    reg           arg_vld_q;
    reg [w - 1:0] arg_q;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
            arg_vld_q <= 1'b0;
        else if (clk_en)
            arg_vld_q <= arg_vld;
    
    always @ (posedge clk)
        if (clk_en & arg_vld)
            arg_q <= arg;

    reg [3:0] shift;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
        begin
            shift <= 4'b0;
        end
        else if (clk_en)
        begin
            if (arg_vld_q)
                shift <= 4'b1000;
            else
                shift <= shift >> 1;
        end

    assign res_vld = shift [0];

    reg  [w - 1:0] mul_q;
    wire [w - 1:0] mul_d = (arg_vld_q ? arg_q : mul_q) * arg_q;

    // TODO: reduce switching

    always @(posedge clk)
        if (clk_en && (arg_vld_q || shift [3:1] != 3'b0))
            mul_q <= mul_d;

    assign res = mul_q;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_en_multi_cycle_always
    # (.w (8))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule
module pow_5_pipe_always
# (
    parameter w = 8
)
(
    input                clk,
    input                rst_n,
    input                arg_vld,
    input  [    w - 1:0] arg,
    output [        4:0] res_vld,
    output [5 * w - 1:0] res
);

    reg [w - 1:0] arg1, arg2, arg3, arg4;
    reg [w - 1:0] pow2, pow3, pow4, pow5;
    reg arg_vld_1, arg_vld_2, arg_vld_3, arg_vld_4, arg_vld_5;

    always @ (posedge clk or negedge rst_n)
        if (! rst_n)
        begin
            arg_vld_1 <= 1'b0;
            arg_vld_2 <= 1'b0;
            arg_vld_3 <= 1'b0;
            arg_vld_4 <= 1'b0;
            arg_vld_5 <= 1'b0;
        end
        else
        begin
            arg_vld_1 <= arg_vld;
            arg_vld_2 <= arg_vld_1;
            arg_vld_3 <= arg_vld_2;
            arg_vld_4 <= arg_vld_3;
            arg_vld_5 <= arg_vld_4;
        end

    always @ (posedge clk)
    begin
        arg1 <= arg;
        arg2 <= arg1;
        arg3 <= arg2;
        arg4 <= arg3;

        pow2 <= arg1 * arg1;
        pow3 <= pow2 * arg2;
        pow4 <= pow3 * arg3;
        pow5 <= pow4 * arg4;
    end

    assign res_vld = { arg_vld_1 , arg_vld_2 , arg_vld_3 , arg_vld_4 , arg_vld_5 };
    assign res     = { arg1      , pow2      , pow3      , pow4      , pow5      };

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_5_pipe_always
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk ),
        .rst_n   ( rst_n    ),
        .arg_vld ( key [0]  ),
        .arg     ( sw       ),
        .res_vld ( res_vld  ),
        .res     ( res      )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_n_en_pipe_always
# (
    parameter w = 8, n = 5
)
(
    input                      clk,
    input                      rst_n,
    input                      clk_en,
    input                      arg_vld,
    input      [     w - 1:0 ] arg,
    output reg [ n     - 1:0 ] res_vld,
    output reg [ n * w - 1:0 ] res
);

    reg [ w - 1 : 0 ] arg_reg [ 1 : n - 1 ];
    reg [ w - 1 : 0 ] pow     [ 2 : n     ];
    reg [     1 : n ] arg_vld_reg;

    integer i;

    always @ (posedge clk or negedge rst_n)

        if (! rst_n)
        begin
            for (i = 1; i <= n; i = i + 1)
                arg_vld_reg [i] <= 1'b0;
        end
        else if (clk_en)
        begin
            arg_vld_reg [1] <= arg_vld;

            for (i = 1; i <= n - 1; i = i + 1)
                arg_vld_reg [i + 1] <= arg_vld_reg [i];
        end

    always @ (posedge clk)

        if (clk_en)
        begin
            arg_reg [1] <= arg;

            for (i = 1; i <= n - 2; i = i + 1)
                arg_reg [i + 1] <= arg_reg [i];

            pow [2] <= arg_reg [1] * arg_reg [1];

            for (i = 2; i <= n - 1; i = i + 1)
                pow [i + 1] <= pow [i] * arg_reg [i];
        end

    always @*
    begin
        for (i = 1; i <= n; i = i + 1)
            res_vld [n - i] = arg_vld_reg [i];

        res [(n - 1) * w +: w] = arg_reg [1];

        for (i = 2; i <= n; i = i + 1)
            res [(n - i) * w +: w] = pow [i];
    end

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_n_en_pipe_always
    # (.w (8), .n (5))
    i_pow_5
    (
        .clk     ( fast_clk    ),
        .rst_n   ( rst_n       ),
        .clk_en  ( fast_clk_en ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( res         )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_5_pipe_struct
# (
    parameter w = 8
)
(
    input                clk,
    input                rst_n,
    input                arg_vld,
    input  [    w - 1:0] arg,
    output [        4:0] res_vld,
    output [5 * w - 1:0] res
);

    wire           arg_vld_q_1;
    wire [w - 1:0] arg_q_1;

    reg_rst_n        i0_arg_vld (clk, rst_n, arg_vld, arg_vld_q_1);
    reg_no_rst # (w) i0_arg     (clk, arg, arg_q_1);

    assign res_vld [4         ] = arg_vld_q_1;
    assign res     [4 * w +: w] = arg_q_1;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_1 = arg_q_1 * arg_q_1;

    wire           arg_vld_q_2;
    wire [w - 1:0] arg_q_2;
    wire [w - 1:0] mul_q_2;

    reg_rst_n        i1_arg_vld ( clk , rst_n  , arg_vld_q_1 , arg_vld_q_2 );
    reg_no_rst # (w) i1_arg     ( clk ,          arg_q_1     , arg_q_2     );
    reg_no_rst # (w) i1_mul     ( clk ,          mul_d_1     , mul_q_2     );

    assign res_vld [3         ] = arg_vld_q_2;
    assign res     [3 * w +: w] = mul_q_2;
    
    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_2 = mul_q_2 * arg_q_2;

    wire           arg_vld_q_3;
    wire [w - 1:0] arg_q_3;
    wire [w - 1:0] mul_q_3;

    reg_rst_n        i2_arg_vld ( clk , rst_n  , arg_vld_q_2 , arg_vld_q_3 );
    reg_no_rst # (w) i2_arg     ( clk ,          arg_q_2     , arg_q_3     );
    reg_no_rst # (w) i2_mul     ( clk ,          mul_d_2     , mul_q_3     );

    assign res_vld [2         ] = arg_vld_q_3;
    assign res     [2 * w +: w] = mul_q_3;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_3 = mul_q_3 * arg_q_3;

    wire           arg_vld_q_4;
    wire [w - 1:0] arg_q_4;
    wire [w - 1:0] mul_q_4;

    reg_rst_n        i3_arg_vld ( clk , rst_n  , arg_vld_q_3 , arg_vld_q_4 );
    reg_no_rst # (w) i3_arg     ( clk ,          arg_q_3     , arg_q_4     );
    reg_no_rst # (w) i3_mul     ( clk ,          mul_d_3     , mul_q_4     );

    assign res_vld [1         ] = arg_vld_q_4;
    assign res     [1 * w +: w] = mul_q_4;

    //------------------------------------------------------------------------

    wire [w - 1:0] mul_d_4 = mul_q_4 * arg_q_4;

    wire           arg_vld_q_5;
    wire [w - 1:0] arg_q_5;
    wire [w - 1:0] mul_q_5;

    reg_rst_n        i4_arg_vld ( clk , rst_n  , arg_vld_q_4 , arg_vld_q_5 );
    reg_no_rst # (w) i4_arg     ( clk ,          arg_q_4     , arg_q_5     );
    reg_no_rst # (w) i4_mul     ( clk ,          mul_d_4     , mul_q_5     );

    assign res_vld [0         ] = arg_vld_q_5;
    assign res     [0 * w +: w] = mul_q_5;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire [ 4:0] res_vld;
    wire [39:0] res;

    pow_5_pipe_struct
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk ),
        .rst_n   ( rst_n    ),
        .arg_vld ( key [0]  ),
        .arg     ( sw       ),
        .res_vld ( res_vld  ),
        .res     ( res      )
    );

    assign disp_en  =
    {
        res_vld [3], res_vld [3],
        res_vld [2], res_vld [2],
        res_vld [1], res_vld [1],
        res_vld [0], res_vld [0]
    };

    assign disp = res [31:0];

    assign disp_dot = 8'b0;

endmodule
module pow_5_multi_cycle_struct_todo
# (
    parameter w = 8
)
(
    input            clk,
    input            rst_n,
    input            arg_vld,
    input  [w - 1:0] arg,
    output           res_vld,
    output [w - 1:0] res
);

    wire             arg_vld_q;
    wire   [w - 1:0] arg_q;

    reg_rst_n        i_arg_vld (clk, rst_n, arg_vld, arg_vld_q);
    reg_no_rst # (w) i_arg     (clk, arg, arg_q);

    wire [4:0] shift_q;
    wire [4:0] shift_d = arg_vld_q ? 5'b10000 : shift_q >> 1;
   
    reg_rst_n # (5) i_shift (clk, rst_n, shift_d, shift_q);
    
    assign res_vld = shift_q [0];

    // TODO: save cycle
    // TODO: reduce switching

    wire [w - 1:0] mul_q;
    wire [w - 1:0] mul_d = arg_vld_q ? arg_q : mul_q * arg_q;

    reg_no_rst # (w) i_mul (clk, mul_d, mul_q);
    
    assign res = mul_q;

endmodule
module board_independent_wrapper
(
    input         fast_clk,
    input         slow_clk,
    input         rst_n,
    input         fast_clk_en,
    input  [ 3:0] key,
    input  [ 7:0] sw,
    output [ 7:0] led,
    output [ 7:0] disp_en,
    output [31:0] disp,
    output [ 7:0] disp_dot
);

    wire res_vld;
    
    assign led  = { 8 { res_vld } };

    pow_5_multi_cycle_struct_todo
    # (.w (8))
    i_pow_5
    (
        .clk     ( slow_clk    ),
        .rst_n   ( rst_n       ),
        .arg_vld ( key [0]     ),
        .arg     ( sw          ),
        .res_vld ( res_vld     ),
        .res     ( disp [7:0]  )
    );
    
    assign disp_en  = 8'b00000011;
    assign disp_dot = { 7'b0000000, res_vld };

endmodule