dakies/OSS_Verilog huggingface dataset:
module \$__outpad (input I, output O);
   fiftyfivenm_io_obuf _TECHMAP_REPLACE_ (.o(O), .i(I), .oe(1'b1));
endmodule
module \$lut (A, Y);
   parameter WIDTH  = 0;
   parameter LUT    = 0;
   (* force_downto *)
   input [WIDTH-1:0] A;
   output            Y;
   generate
      if (WIDTH == 1) begin
	   assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function
      end else
      if (WIDTH == 2) begin
           fiftyfivenm_lcell_comb #(.lut_mask({4{LUT}}), .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(1'b1),.datad(1'b1));
      end else
      if(WIDTH == 3) begin
	      fiftyfivenm_lcell_comb #(.lut_mask({2{LUT}}), .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(A[2]),.datad(1'b1));
      end else
      if(WIDTH == 4) begin
         fiftyfivenm_lcell_comb #(.lut_mask(LUT), .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y), .dataa(A[0]), .datab(A[1]), .datac(A[2]),.datad(A[3]));
      end else
	   wire _TECHMAP_FAIL_ = 1;
   endgenerate
endmodule //
module fiftyfivenm_io_ibuf
  (output o, input i, input ibar);
   assign ibar = ibar;
   assign o    = i;
endmodule // fiftyfivenm_io_ibuf
module fiftyfivenm_io_obuf
  (output o, input i, input oe);
   assign o  = i;
   assign oe = oe;
endmodule // fiftyfivenm_io_obuf
module fiftyfivenm_lcell_comb
  (output combout, cout,
   input dataa, datab, datac, datad, cin);

   /* Internal parameters which define the behaviour
    of the LUT primitive.
    lut_mask define the lut function, can be expressed in 16-digit bin or hex.
    sum_lutc_input define the type of LUT (combinational | arithmetic).
    dont_touch for retiming || carry options.
    lpm_type for WYSIWYG */

   parameter lut_mask = 16'hFFFF;
   parameter dont_touch = "off";
   parameter lpm_type = "fiftyfivenm_lcell_comb";
   parameter sum_lutc_input = "datac";

   reg [1:0] lut_type;
   reg       cout_rt;
   reg       combout_rt;
   wire      dataa_w;
   wire      datab_w;
   wire      datac_w;
   wire      datad_w;
   wire      cin_w;

   assign dataa_w = dataa;
   assign datab_w = datab;
   assign datac_w = datac;
   assign datad_w = datad;

   function lut_data;
      input [15:0] mask;
      input        dataa, datab, datac, datad;
      reg [7:0]    s3;
      reg [3:0]    s2;
      reg [1:0]    s1;
      begin
         s3 = datad ? mask[15:8] : mask[7:0];
         s2 = datac ?   s3[7:4]  :   s3[3:0];
         s1 = datab ?   s2[3:2]  :   s2[1:0];
         lut_data = dataa ? s1[1] : s1[0];
      end

   endfunction

   initial begin
      if (sum_lutc_input == "datac") lut_type = 0;
      else
        if (sum_lutc_input == "cin")   lut_type = 1;
        else begin
           $error("Error in sum_lutc_input. Parameter %s is not a valid value.\n", sum_lutc_input);
           $finish();
        end
   end

   always @(dataa_w or datab_w or datac_w or datad_w or cin_w) begin
      if (lut_type == 0) begin // logic function
         combout_rt = lut_data(lut_mask, dataa_w, datab_w,
                               datac_w, datad_w);
      end
      else if (lut_type == 1) begin // arithmetic function
         combout_rt = lut_data(lut_mask, dataa_w, datab_w,
                               cin_w, datad_w);
      end
      cout_rt = lut_data(lut_mask, dataa_w, datab_w, cin_w, 'b0);
   end

   assign combout = combout_rt & 1'b1;
   assign cout = cout_rt & 1'b1;

endmodule // fiftyfivenm_lcell_comb
module \$__inpad (input I, output O);
   cyclone10lp_io_ibuf _TECHMAP_REPLACE_ (.o(O), .i(I), .ibar(1'b0));
endmodule
module \$__outpad (input I, output O);
   cyclone10lp_io_obuf _TECHMAP_REPLACE_ (.o(O), .i(I), .oe(1'b1));
endmodule
module \$lut (A, Y);
   parameter WIDTH  = 0;
   parameter LUT    = 0;
   (* force_downto *)
   input [WIDTH-1:0] A;
   output            Y;
   generate
      if (WIDTH == 1) begin
	 assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function
      end else
        if (WIDTH == 2) begin
           cyclone10lp_lcell_comb #(.lut_mask({4{LUT}}),
                                   .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
                                                                                .dataa(A[0]),
                                                                                .datab(A[1]),
                                                                                .datac(1'b1),
                                                                                .datad(1'b1));
        end else
          if(WIDTH == 3) begin
	     cyclone10lp_lcell_comb #(.lut_mask({2{LUT}}),
                                     .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
                                                                                  .dataa(A[0]),
                                                                                  .datab(A[1]),
                                                                                  .datac(A[2]),
                                                                                  .datad(1'b1));
          end else
            if(WIDTH == 4) begin
	       cyclone10lp_lcell_comb #(.lut_mask(LUT),
                                       .sum_lutc_input("datac")) _TECHMAP_REPLACE_ (.combout(Y),
                                                                                    .dataa(A[0]),
                                                                                    .datab(A[1]),
                                                                                    .datac(A[2]),
                                                                                    .datad(A[3]));
            end else
	             wire _TECHMAP_FAIL_ = 1;
   endgenerate

endmodule
module cyclone10lp_io_ibuf
  (output o, input i, input ibar);
   assign ibar = ibar;
   assign o    = i;
endmodule // cyclone10lp_io_ibuf
module cyclone10lp_io_obuf
  (output o, input i, input oe);
   assign o  = i;
   assign oe = oe;
endmodule // cyclone10lp_io_obuf
module cyclone10lp_lcell_comb
  (output combout, cout,
   input dataa, datab, datac, datad, cin);

   /* Internal parameters which define the behaviour
    of the LUT primitive.
    lut_mask define the lut function, can be expressed in 16-digit bin or hex.
    sum_lutc_input define the type of LUT (combinational | arithmetic).
    dont_touch for retiming || carry options.
    lpm_type for WYSIWYG */

   parameter lut_mask   = 16'hFFFF;
   parameter dont_touch = "off";
   parameter lpm_type   = "cyclone10lp_lcell_comb";
   parameter sum_lutc_input = "datac";

   reg [1:0]                        lut_type;
   reg                              cout_rt;
   reg                              combout_rt;
   wire                             dataa_w;
   wire                             datab_w;
   wire                             datac_w;
   wire                             datad_w;
   wire                             cin_w;

   assign dataa_w = dataa;
   assign datab_w = datab;
   assign datac_w = datac;
   assign datad_w = datad;

   function lut_data;
      input [15:0]                  mask;
      input                         dataa, datab, datac, datad;
      reg [7:0]                     s3;
      reg [3:0]                     s2;
      reg [1:0]                     s1;
      begin
         s3 = datad ? mask[15:8] : mask[7:0];
         s2 = datac ?   s3[7:4]  :   s3[3:0];
         s1 = datab ?   s2[3:2]  :   s2[1:0];
         lut_data = dataa ? s1[1] : s1[0];
      end

   endfunction

   initial begin
      if (sum_lutc_input == "datac") lut_type = 0;
      else
        if (sum_lutc_input == "cin")   lut_type = 1;
        else begin
           $error("Error in sum_lutc_input. Parameter %s is not a valid value.\n", sum_lutc_input);
           $finish();
        end
   end

   always @(dataa_w or datab_w or datac_w or datad_w or cin_w) begin
      if (lut_type == 0) begin // logic function
         combout_rt = lut_data(lut_mask, dataa_w, datab_w,
                               datac_w, datad_w);
      end
      else if (lut_type == 1) begin // arithmetic function
         combout_rt = lut_data(lut_mask, dataa_w, datab_w,
                               cin_w, datad_w);
      end
      cout_rt = lut_data(lut_mask, dataa_w, datab_w, cin_w, 'b0);
   end

   assign combout = combout_rt & 1'b1;
   assign cout = cout_rt & 1'b1;

endmodule // cyclone10lp_lcell_comb
module __MUL27X27(A, B, Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;
parameter A_WIDTH = 27;
parameter B_WIDTH = 27;
parameter Y_WIDTH = 54;

input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;

MISTRAL_MUL27X27 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));

endmodule
module __MUL18X18(A, B, Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;
parameter A_WIDTH = 18;
parameter B_WIDTH = 18;
parameter Y_WIDTH = 36;

input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;

MISTRAL_MUL18X18 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));

endmodule
module __MUL9X9(A, B, Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;
parameter A_WIDTH = 9;
parameter B_WIDTH = 9;
parameter Y_WIDTH = 18;

input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;

MISTRAL_MUL9X9 _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));

endmodule
module altera_std_synchronizer(clk, din, dout, reset_n);

parameter depth = 2;

input clk;
input reset_n;
input din;
output dout;

endmodule
module altddio_in (
    datain,    // required port, DDR input data
    inclock,   // required port, input reference clock to sample data by
    inclocken, // enable data clock
    aset,      // asynchronous set
    aclr,      // asynchronous clear
    sset,      // synchronous set
    sclr,      // synchronous clear
    dataout_h, // data sampled at the rising edge of inclock
    dataout_l  // data sampled at the falling edge of inclock
);

parameter width = 1;
parameter power_up_high = "OFF";
parameter invert_input_clocks = "OFF";
parameter intended_device_family = "Stratix";
parameter lpm_type = "altddio_in";
parameter lpm_hint = "UNUSED";

input [width-1:0] datain;
input inclock;
input inclocken;
input aset;
input aclr;
input sset;
input sclr;

output [width-1:0] dataout_h;
output [width-1:0] dataout_l;

endmodule
module altddio_out (
    datain_h,
    datain_l,
    outclock,
    outclocken,
    aset,
    aclr,
    sset,
    sclr,
    oe,
    dataout,
    oe_out
);

parameter width = 1;
parameter power_up_high = "OFF";
parameter oe_reg = "UNUSED";
parameter extend_oe_disable = "UNUSED";
parameter intended_device_family = "Stratix";
parameter invert_output = "OFF";
parameter lpm_type = "altddio_out";
parameter lpm_hint = "UNUSED";

input [width-1:0] datain_h;
input [width-1:0] datain_l;
input outclock;
input outclocken;
input aset;
input aclr;
input sset;
input sclr;
input oe;

output [width-1:0] dataout;
output [width-1:0] oe_out;

endmodule
module altddio_bidir (
    datain_h,
    datain_l,
    inclock,
    inclocken,
    outclock,
    outclocken,
    aset,
    aclr,
    sset,
    sclr,
    oe,
    dataout_h,
    dataout_l,
    combout,
    oe_out,
    dqsundelayedout,
    padio
);

// GLOBAL PARAMETER DECLARATION
parameter width = 1; // required parameter
parameter power_up_high = "OFF";
parameter oe_reg = "UNUSED";
parameter extend_oe_disable = "UNUSED";
parameter implement_input_in_lcell = "UNUSED";
parameter invert_output = "OFF";
parameter intended_device_family = "Stratix";
parameter lpm_type = "altddio_bidir";
parameter lpm_hint = "UNUSED";

// INPUT PORT DECLARATION
input [width-1:0] datain_h;
input [width-1:0] datain_l;
input inclock;
input inclocken;
input outclock;
input outclocken;
input aset;
input aclr;
input sset;
input sclr;
input oe;

// OUTPUT PORT DECLARATION
output [width-1:0] dataout_h;
output [width-1:0] dataout_l;
output [width-1:0] combout;
output [width-1:0] oe_out;
output [width-1:0] dqsundelayedout;
// BIDIRECTIONAL PORT DECLARATION
inout  [width-1:0] padio;

endmodule
module altiobuf_in(datain, dataout);

parameter enable_bus_hold = "FALSE";
parameter use_differential_mode = "FALSE";
parameter number_of_channels = 1;

input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;

endmodule
module altiobuf_out(datain, dataout);

parameter enable_bus_hold = "FALSE";
parameter use_differential_mode = "FALSE";
parameter use_oe = "FALSE";
parameter number_of_channels = 1;

input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;

endmodule
module altiobuf_bidir(dataio, oe, datain, dataout);

parameter number_of_channels = 1;
parameter enable_bus_hold = "OFF";

inout [number_of_channels-1:0] dataio;
input [number_of_channels-1:0] datain;
output [number_of_channels-1:0] dataout;
input [number_of_channels-1:0] oe;

endmodule
module altsyncram(clock0, clock1, address_a, data_a, rden_a, wren_a, byteena_a, q_a, addressstall_a, address_b, data_b, rden_b, wren_b, byteena_b, q_b, addressstall_b, clocken0, clocken1, clocken2, clocken3, aclr0, aclr1, eccstatus);

parameter lpm_type = "altsyncram";
parameter operation_mode = "dual_port";
parameter ram_block_type = "auto";
parameter intended_device_family = "auto";
parameter power_up_uninitialized = "false";
parameter read_during_write_mode_mixed_ports = "dontcare";
parameter byte_size = 8;
parameter widthad_a = 1;
parameter width_a = 1;
parameter width_byteena_a = 1;
parameter numwords_a = 1;
parameter clock_enable_input_a = "clocken0";
parameter widthad_b = 1;
parameter width_b = 1;
parameter numwords_b = 1;
parameter address_aclr_b = "aclr0";
parameter address_reg_b = "";
parameter outdata_aclr_b = "aclr0";
parameter outdata_reg_b = "";
parameter clock_enable_input_b = "clocken0";
parameter clock_enable_output_b = "clocken0";

input clock0, clock1;
input [widthad_a-1:0] address_a;
input [width_a-1:0] data_a;
input rden_a;
input wren_a;
input [(width_a/8)-1:0] byteena_a;
input addressstall_a;

output [width_a-1:0] q_a;

input wren_b;
input rden_b;
input [widthad_b-1:0] address_b;
input [width_b-1:0] data_b;
input [(width_b/8)-1:0] byteena_b;
input addressstall_b;

output [width_b-1:0] q_b;

input clocken0;
input clocken1;
input clocken2;
input clocken3;

input aclr0;
input aclr1;

output eccstatus;

endmodule
module cyclonev_mlab_cell(portaaddr, portadatain, portbaddr, portbdataout, ena0, clk0, clk1);

parameter logical_ram_name = "";
parameter logical_ram_depth = 32;
parameter logical_ram_width = 20;
parameter mixed_port_feed_through_mode = "new";
parameter first_bit_number = 0;
parameter first_address = 0;
parameter last_address = 31;
parameter address_width = 5;
parameter data_width = 1;
parameter byte_enable_mask_width = 1;
parameter port_b_data_out_clock = "NONE";
parameter [639:0] mem_init0 = 640'b0;

input [address_width-1:0] portaaddr, portbaddr;
input [data_width-1:0] portadatain;
output [data_width-1:0] portbdataout;
input ena0, clk0, clk1;

endmodule
module cyclonev_mac(ax, ay, resulta);

parameter ax_width = 9;
parameter signed_max = "true";
parameter ay_scan_in_width = 9;
parameter signed_may = "true";
parameter result_a_width = 18;
parameter operation_mode = "M9x9";

input [ax_width-1:0] ax;
input [ay_scan_in_width-1:0] ay;
output [result_a_width-1:0] resulta;

endmodule
module cyclone10gx_mac(ax, ay, resulta);

parameter ax_width = 18;
parameter signed_max = "true";
parameter ay_scan_in_width = 18;
parameter signed_may = "true";
parameter result_a_width = 36;
parameter operation_mode = "M18X18_FULL";

input [ax_width-1:0] ax;
input [ay_scan_in_width-1:0] ay;
output [result_a_width-1:0] resulta;

endmodule
module cyclonev_ram_block(portaaddr, portadatain, portawe, portbaddr, portbdataout, portbre, clk0);

parameter operation_mode = "dual_port";
parameter logical_ram_name = "";
parameter port_a_address_width = 10;
parameter port_a_data_width = 10;
parameter port_a_logical_ram_depth = 1024;
parameter port_a_logical_ram_width = 10;
parameter port_a_first_address = 0;
parameter port_a_last_address = 1023;
parameter port_a_first_bit_number = 0;
parameter port_b_address_width = 10;
parameter port_b_data_width = 10;
parameter port_b_logical_ram_depth = 1024;
parameter port_b_logical_ram_width = 10;
parameter port_b_first_address = 0;
parameter port_b_last_address = 1023;
parameter port_b_first_bit_number = 0;
parameter port_b_address_clock = "clock0";
parameter port_b_read_enable_clock = "clock0";
parameter mem_init0 = "";
parameter mem_init1 = "";
parameter mem_init2 = "";
parameter mem_init3 = "";
parameter mem_init4 = "";

input [port_a_address_width-1:0] portaaddr;
input [port_b_address_width-1:0] portbaddr;
input [port_a_data_width-1:0] portadatain;
output [port_b_data_width-1:0] portbdataout;
input clk0, portawe, portbre;

endmodule
module cyclone10gx_io_ibuf(i, ibar, dynamicterminationcontrol, o);

parameter differential_mode ="false";
parameter bus_hold = "false";
parameter simulate_z_as = "Z";
parameter lpm_type = "cyclone10gx_io_ibuf";

(* iopad_external_pin *) input i;
(* iopad_external_pin *) input ibar;
input dynamicterminationcontrol;
output o;

endmodule
module cyclone10gx_io_obuf(i, oe, dynamicterminationcontrol, seriesterminationcontrol, parallelterminationcontrol, devoe, o, obar);

parameter open_drain_output = "false";
parameter bus_hold = "false";
parameter shift_series_termination_control = "false";
parameter sim_dynamic_termination_control_is_connected = "false";
parameter lpm_type = "cyclone10gx_io_obuf";

input i;
input oe;
input devoe;
input dynamicterminationcontrol;
input [15:0] seriesterminationcontrol;
input [15:0] parallelterminationcontrol;
(* iopad_external_pin *) output o;
(* iopad_external_pin *) output obar;

endmodule
module cyclonev_clkena(inclk, ena, enaout, outclk);

parameter clock_type = "auto";
parameter ena_register_mode = "always enabled";
parameter lpm_type = "cyclonev_clkena";
parameter ena_register_power_up = "high";
parameter disable_mode = "low";
parameter test_syn = "high";

input inclk;
input ena;
output enaout;
output outclk;

endmodule
module cyclone10gx_clkena(inclk, ena, enaout, outclk);

parameter clock_type = "auto";
parameter ena_register_mode = "always enabled";
parameter lpm_type = "cyclone10gx_clkena";
parameter ena_register_power_up = "high";
parameter disable_mode = "low";
parameter test_syn = "high";

input inclk;
input ena;
output enaout;
output outclk;

endmodule
module cyclonev_oscillator(oscena, clkout, clkout1);

input oscena;
output clkout;
output clkout1;

endmodule
module cyclonev_hps_interface_mpu_general_purpose(gp_in, gp_out);

input [31:0] gp_in;
output [31:0] gp_out;

endmodule
module MISTRAL_MUL27X27(input [26:0] A, input [26:0] B, output [53:0] Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;

`ifdef cyclonev
specify
    (A *> Y) = 3732;
    (B *> Y) = 3928;
endspecify
`endif
`ifdef arriav
// NOTE: Arria V appears to have only one set of timings for all DSP modes...
specify
    (A *> Y) = 1895;
    (B *> Y) = 2053;
endspecify
`endif
`ifdef cyclone10gx
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
specify
    (A *> Y) = 3732;
    (B *> Y) = 3928;
endspecify
`endif

wire [53:0] A_, B_;

if (A_SIGNED)
    assign A_ = $signed(A);
else
    assign A_ = $unsigned(A);

if (B_SIGNED)
    assign B_ = $signed(B);
else
    assign B_ = $unsigned(B);

assign Y = A_ * B_;

endmodule
module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;

`ifdef cyclonev
specify
    (A *> Y) = 3180;
    (B *> Y) = 3982;
endspecify
`endif
`ifdef arriav
// NOTE: Arria V appears to have only one set of timings for all DSP modes...
specify
    (A *> Y) = 1895;
    (B *> Y) = 2053;
endspecify
`endif
`ifdef cyclone10gx
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
specify
    (A *> Y) = 3180;
    (B *> Y) = 3982;
endspecify
`endif

wire [35:0] A_, B_;

if (A_SIGNED)
    assign A_ = $signed(A);
else
    assign A_ = $unsigned(A);

if (B_SIGNED)
    assign B_ = $signed(B);
else
    assign B_ = $unsigned(B);

assign Y = A_ * B_;

endmodule
module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y);

parameter A_SIGNED = 1;
parameter B_SIGNED = 1;

`ifdef cyclonev
specify
    (A *> Y) = 2818;
    (B *> Y) = 3051;
endspecify
`endif
`ifdef arriav
// NOTE: Arria V appears to have only one set of timings for all DSP modes...
specify
    (A *> Y) = 1895;
    (B *> Y) = 2053;
endspecify
`endif
`ifdef cyclone10gx
// TODO: Cyclone 10 GX timings; the below are for Cyclone V
specify
    (A *> Y) = 2818;
    (B *> Y) = 3051;
endspecify
`endif

wire [17:0] A_, B_;

if (A_SIGNED)
    assign A_ = $signed(A);
else
    assign A_ = $unsigned(A);

if (B_SIGNED)
    assign B_ = $signed(B);
else
    assign B_ = $unsigned(B);

assign Y = A_ * B_;

endmodule
module \$_DFFE_PN0P_ (input D, C, R, E, output Q);
    wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
    MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule
module \$_SDFFCE_PP0P_ (input D, C, R, E, output Q);
    wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
    MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(R), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
endmodule
module \$__MISTRAL_M10K (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);

parameter CFG_ABITS = 10;
parameter CFG_DBITS = 10;

input CLK1;
input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
input [CFG_DBITS-1:0] A1DATA;
input A1EN, B1EN;
output reg [CFG_DBITS-1:0] B1DATA;

MISTRAL_M10K #(.CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN));

endmodule
module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);

parameter [63:0] LUT = 64'h0000_0000_0000_0000;

`ifdef cyclonev
specify
    (A => Q) = 605;
    (B => Q) = 583;
    (C => Q) = 510;
    (D => Q) = 512;
    (E => Q) = 400;
    (F => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 387;
    (B => Q) = 375;
    (C => Q) = 316;
    (D => Q) = 317;
    (E => Q) = 319;
    (F => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 275;
    (B => Q) = 272;
    (C => Q) = 175;
    (D => Q) = 165;
    (E => Q) = 162;
    (F => Q) = 53;
endspecify
`endif

assign Q = LUT >> {F, E, D, C, B, A};

endmodule
module MISTRAL_ALUT5(input A, B, C, D, E, output Q);

parameter [31:0] LUT = 32'h0000_0000;

`ifdef cyclonev
specify
    (A => Q) = 583;
    (B => Q) = 510;
    (C => Q) = 512;
    (D => Q) = 400;
    (E => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 375;
    (B => Q) = 316;
    (C => Q) = 317;
    (D => Q) = 319;
    (E => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 272;
    (B => Q) = 175;
    (C => Q) = 165;
    (D => Q) = 162;
    (E => Q) = 53;
endspecify
`endif

assign Q = LUT >> {E, D, C, B, A};

endmodule
module MISTRAL_ALUT4(input A, B, C, D, output Q);

parameter [15:0] LUT = 16'h0000;

`ifdef cyclonev
specify
    (A => Q) = 510;
    (B => Q) = 512;
    (C => Q) = 400;
    (D => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 316;
    (B => Q) = 317;
    (C => Q) = 319;
    (D => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 175;
    (B => Q) = 165;
    (C => Q) = 162;
    (D => Q) = 53;
endspecify
`endif

assign Q = LUT >> {D, C, B, A};

endmodule
module MISTRAL_ALUT3(input A, B, C, output Q);

parameter [7:0] LUT = 8'h00;

`ifdef cyclonev
specify
    (A => Q) = 510;
    (B => Q) = 400;
    (C => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 316;
    (B => Q) = 317;
    (C => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 165;
    (B => Q) = 162;
    (C => Q) = 53;
endspecify
`endif

assign Q = LUT >> {C, B, A};

endmodule
module MISTRAL_ALUT2(input A, B, output Q);

parameter [3:0] LUT = 4'h0;

`ifdef cyclonev
specify
    (A => Q) = 400;
    (B => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 316;
    (B => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 162;
    (B => Q) = 53;
endspecify
`endif

assign Q = LUT >> {B, A};

endmodule
module MISTRAL_NOT(input A, output Q);

`ifdef cyclonev
specify
    (A => Q) = 97;
endspecify
`endif
`ifdef arriav
specify
    (A => Q) = 76;
endspecify
`endif
`ifdef cyclone10gx
specify
    (A => Q) = 53;
endspecify
`endif

assign Q = ~A;

endmodule
module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, /* (* abc9_carry *) */ input CI, output SO, /* (* abc9_carry *) */ output CO);

parameter LUT0 = 16'h0000;
parameter LUT1 = 16'h0000;

`ifdef cyclonev
specify
    (A  => SO) = 1342;
    (B  => SO) = 1323;
    (C  => SO) = 927;
    (D0 => SO) = 887;
    (D1 => SO) = 785;
    (CI => SO) = 368;

    (A  => CO) = 1082;
    (B  => CO) = 1062;
    (C  => CO) = 813;
    (D0 => CO) = 866;
    (D1 => CO) = 1198;
    (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM)
endspecify
`endif
`ifdef arriav
specify
    (A  => SO) = 744;
    (B  => SO) = 732;
    (C  => SO) = 562;
    (D0 => SO) = 576;
    (D1 => SO) = 511;
    (CI => SO) = 249;

    (A  => CO) = 629;
    (B  => CO) = 623;
    (C  => CO) = 530;
    (D0 => CO) = 514;
    (D1 => CO) = 696;
    (CI => CO) = 10; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM)
endspecify
`endif
`ifdef cyclone10gx
specify
    (A  => SO) = 644;
    (B  => SO) = 477;
    (C  => SO) = 416;
    (D0 => SO) = 380;
    (D1 => SO) = 431;
    (CI => SO) = 276;

    (A  => CO) = 525;
    (B  => CO) = 433;
    (C  => CO) = 712;
    (D0 => CO) = 653;
    (D1 => CO) = 593;
    (CI => CO) = 16;
endspecify
`endif

wire q0, q1;

assign q0 = LUT0 >> {D0, C, B, A};
assign q1 = LUT1 >> {D1, C, B, A};

assign {CO, SO} = q0 + !q1 + CI;

endmodule
module MISTRAL_IB((* iopad_external_pin *)  input PAD, output O);
	assign O = PAD;
endmodule
module MISTRAL_OB((* iopad_external_pin *)  output PAD, input I);
	assign PAD = I;
endmodule
module MISTRAL_IO((* iopad_external_pin *)  inout PAD, input I, input OE, output O);
	assign PAD = OE ? I : 1'bz;
	assign O = PAD;
endmodule
module MISTRAL_CLKBUF (
	input A,
	(* clkbuf_driver *) output Q
);
	assign Q = A;
endmodule
module MISTRAL_FF(
    input DATAIN,
    (* clkbuf_sink *) input CLK,
    input ACLR, ENA, SCLR, SLOAD, SDATA,
    output reg Q
);

`ifdef cyclonev
specify
    if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 731;
    if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 890;
    if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 618;

    $setup(DATAIN, posedge CLK, /* -196 */ 0);
    $setup(ENA, posedge CLK, /* -196 */ 0);
    $setup(SCLR, posedge CLK, /* -196 */ 0);
    $setup(SLOAD, posedge CLK, /* -196 */ 0);
    $setup(SDATA, posedge CLK, /* -196 */ 0);

    if (ACLR === 1'b0) (ACLR => Q) = 282;
endspecify
`endif
`ifdef arriav
specify
    if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470;
    if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633;
    if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439;

    $setup(DATAIN, posedge CLK, /* -170 */ 0);
    $setup(ENA, posedge CLK, /* -170 */ 0);
    $setup(SCLR, posedge CLK, /* -170 */ 0);
    $setup(SLOAD, posedge CLK, /* -170 */ 0);
    $setup(SDATA, posedge CLK, /* -170 */ 0);

    if (ACLR === 1'b0) (ACLR => Q) = 215;
endspecify
`endif
`ifdef cyclone10gx
specify
    // TODO (long-term): investigate these numbers.
    // It seems relying on the Quartus Timing Analyzer was not the best idea; it's too fiddly.
    if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 219;
    if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 219;
    if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 219;

    $setup(DATAIN, posedge CLK, 268);
    $setup(ENA, posedge CLK, 268);
    $setup(SCLR, posedge CLK, 268);
    $setup(SLOAD, posedge CLK, 268);
    $setup(SDATA, posedge CLK, 268);

    if (ACLR === 1'b0) (ACLR => Q) = 0;
endspecify
`endif

initial begin
    // Altera flops initialise to zero.
	Q = 0;
end

always @(posedge CLK, negedge ACLR) begin
    // Asynchronous clear
    if (!ACLR) Q <= 0;
    // Clock-enable
	else if (ENA) begin
        // Synchronous clear
        if (SCLR) Q <= 0;
        // Synchronous load
        else if (SLOAD) Q <= SDATA;
        else Q <= DATAIN;
    end
end

endmodule
module cyclonev_io_ibuf
  (output o,
   (* iopad_external_pin *) input i,
   (* iopad_external_pin *) input ibar,
   input dynamicterminationcontrol);

   parameter differential_mode = "false";
   parameter bus_hold = "false";
   parameter simulate_z_as = "Z";
   parameter lpm_type = "cyclonev_io_ibuf";

   assign o    = i;
endmodule // cyclonev_io_ibuf
module cyclonev_io_obuf
  ((* iopad_external_pin *) output o,
   input i, oe, dynamicterminationcontrol,
   input [15:0] seriesterminationcontrol, parallelterminationcontrol,
   input devoe,
   (* iopad_external_pin *) output obar);

   parameter open_drain_output = "false";
   parameter bus_hold = "false";
   parameter shift_series_termination_control = "false";
   parameter sim_dynamic_termination_control_is_connected = "false";
   parameter lpm_type = "cyclonev_io_obuf";

   assign o  = oe ? i : 1'bz;
endmodule // cyclonev_io_obuf
module cyclonev_lcell_comb
  (output combout, cout, sumout, shareout,
   input dataa, datab, datac, datad,
   input datae, dataf, datag, cin,
   input sharein);

   parameter lut_mask      = 64'hFFFFFFFFFFFFFFFF;
   parameter dont_touch    = "off";
   parameter lpm_type      = "cyclonev_lcell_comb";
   parameter shared_arith  = "off";
   parameter extended_lut  = "off";

   // Internal variables
   // Sub mask for fragmented LUTs
   wire [15:0] mask_a, mask_b, mask_c, mask_d;
   // Independent output for fragmented LUTs
   wire        output_0, output_1, output_2, output_3;
   // Extended mode uses mux to define the output
   wire        mux_0, mux_1;
   // Input for hold the shared LUT mode value
   wire        shared_lut_alm;

   // Simulation model of 4-input LUT
   function lut4;
      input [15:0] mask;
      input        dataa, datab, datac, datad;
      reg [7:0]    s3;
      reg [3:0]    s2;
      reg [1:0]    s1;
      begin
         s3   = datad ? mask[15:8] : mask[7:0];
         s2   = datac ?   s3[7:4]  :   s3[3:0];
         s1   = datab ?   s2[3:2]  :   s2[1:0];
         lut4 = dataa ? s1[1] : s1[0];
      end
   endfunction // lut4

   // Simulation model of 5-input LUT
   function lut5;
      input [31:0] mask; // wp-01003.pdf, page 3: "a 5-LUT can be built with two 4-LUTs and a multiplexer.
      input        dataa, datab, datac, datad, datae;
      reg          upper_lut_value;
      reg          lower_lut_value;
      begin
         upper_lut_value = lut4(mask[31:16], dataa, datab, datac, datad);
         lower_lut_value = lut4(mask[15:0], dataa, datab, datac, datad);
         lut5            = (datae) ? upper_lut_value : lower_lut_value;
      end
   endfunction // lut5

   // Simulation model of 6-input LUT
   function lut6;
      input [63:0] mask;
      input        dataa, datab, datac, datad, datae, dataf;
      reg          upper_lut_value;
      reg          lower_lut_value;
      reg          out_0, out_1, out_2, out_3;
      begin
         upper_lut_value = lut5(mask[63:32], dataa, datab, datac, datad, datae);
         lower_lut_value = lut5(mask[31:0], dataa, datab, datac, datad, datae);
         lut6            = (dataf) ?  upper_lut_value : lower_lut_value;
      end
   endfunction // lut6

   assign {mask_a, mask_b, mask_c, mask_d} = {lut_mask[15:0], lut_mask[31:16], lut_mask[47:32], lut_mask[63:48]};
`ifdef ADVANCED_ALM
   always @(*) begin
      if(extended_lut == "on")
        shared_lut_alm = datag;
      else
        shared_lut_alm = datac;
      // Build the ALM behaviour
      out_0 = lut4(mask_a, dataa, datab, datac, datad);
      out_1 = lut4(mask_b, dataa, datab, shared_lut_alm, datad);
      out_2 = lut4(mask_c, dataa, datab, datac, datad);
      out_3 = lut4(mask_d, dataa, datab, shared_lut_alm, datad);
   end
`else
   `ifdef DEBUG
       initial $display("Advanced ALM lut combine is not implemented yet");
   `endif
`endif
endmodule // cyclonev_lcell_comb
module testbench();

parameter DATA_WIDTH = 32;
parameter ADDR_WIDTH = 32;
parameter MAIN_FRE   = 100; //unit MHz
reg                   sys_clk = 0;
reg                   sys_rst = 1;
reg [DATA_WIDTH-1:0]  data = 0;
reg [ADDR_WIDTH-1:0]  addr = 0;

always begin
    #(500/MAIN_FRE) sys_clk = ~sys_clk;
end

always begin
    #50 sys_rst = 0;
end

always @(posedge sys_clk) begin
    if (sys_rst) 
        addr = 0;
    else      
        addr = addr + 1;
end
always @(posedge sys_clk) begin
    if (sys_rst) 
        data = 0;
    else      
        data = data + 1;
end

//Instance 


initial begin            
    $dumpfile("wave.vcd");        
    $dumpvars(0, testbench);    
    #50000 $finish;
end

endmodule  //TOP
module phase_acc(clr,en,rst,valid_out1,clk,add_sub,sel,D,Q);
    parameter DATASIZE=16;
    input  clr,en,rst,clk,add_sub,sel,valid_out1;
    input  [DATASIZE-1:0] D;
    output [DATASIZE:0]   Q;

    reg count0,count1,count2,count3;
    reg [DATASIZE:0] b_tmp,b_tmp0,b_tmp1,b_tmp2;
    reg [3:0] sum0;
    reg [7:0] sum1;
    reg [11:0] sum2;
    reg [16:0] sum3;
    reg add_sub0,add_sub1,add_sub2;
    reg clr0,clr1,clr2;
   
    always @(posedge clk) begin
        case({clr,add_sub})
            2'b00:{count0,sum0}<={1'b0,sum0}+{1'b0,D[3:0]};
            2'b01:{count0,sum0}<={1'b0,sum0}-{1'b0,D[3:0]};
            2'b10:{count0,sum0}<=5'b0+{1'b0,D[3:0]};
            default:{count0,sum0}<=5'b0-{1'b0,D[3:0]};
        endcase
        b_tmp0<=D;
        clr0<=clr;
        add_sub0<=add_sub;
    end
    
    always @(posedge clk)
    begin
        case({clr0,add_sub0})
            2'b00:{count1,sum1}<={{1'b0,sum1[7:4]}+{1'b0,b_tmp0[7:4]}+count0,sum0};
            2'b01:{count1,sum1}<={{1'b0,sum1[7:4]}-{1'b0,b_tmp0[7:4]}-count0,sum0};
            2'b10:{count1,sum1}<=5'b0+{1'b0,b_tmp0[7:4]};
            default:{count1,sum1}<=5'b0-{1'b0,b_tmp0[7:4]};
        endcase
        b_tmp1<=b_tmp0;
        clr1<=clr0;
        add_sub1<=add_sub0;
    end
    
    always @(posedge clk)
    begin
        case({clr1,add_sub1})
            2'b00:{count2,sum2}<={{1'b0,sum2[11:8]}+{1'b0,b_tmp1[11:8]}+count1,sum1};
            2'b01:{count2,sum2}<={{1'b0,sum2[11:8]}-{1'b0,b_tmp1[11:8]}-count1,sum1};
            2'b10:{count2,sum2}<=5'b0+{1'b0,b_tmp1[11:8]};
            default:{count2,sum2}<=5'b0-{1'b0,b_tmp1[11:8]};
        endcase
        b_tmp2<=b_tmp1;
        clr2<=clr1;
        add_sub2<=add_sub1;
    end
    
    always @(posedge clk) begin
        case({clr2,add_sub2})
            2'b00:sum3<={sum3[16:12]+{1'b0,b_tmp2[15:12]}+count2,sum2};
            2'b01:sum3<={sum3[16:12]-{1'b0,b_tmp2[15:12]}-count2,sum2};
            2'b10:sum3<=5'b0+{1'b0,b_tmp2[15:12]};
            default:sum3<=5'b0-{1'b0,b_tmp2[15:12]};
        endcase
    end
assign Q=sum3;
endmodule
module	Sort3 (
	input				clk,
	input				rst_n,
	
	input		[7:0]	data1, data2, data3,
	output	reg	[7:0]	max_data, mid_data, min_data
);

//-----------------------------------
//Sort of 3 datas	
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		max_data <= 0;
		mid_data <= 0;
		min_data <= 0;
	end
	else begin
		//get the max value
		if(data1 >= data2 && data1 >= data3)
			max_data <= data1;
		else if(data2 >= data1 && data2 >= data3)
			max_data <= data2;
		else//(data3 >= data1 && data3 >= data2)
			max_data <= data3;

		//get the mid value
		if((data1 >= data2 && data1 <= data3) || (data1 >= data3 && data1 <= data2))
			mid_data <= data1;
		else if((data2 >= data1 && data2 <= data3) || (data2 >= data3 && data2 <= data1))
			mid_data <= data2;
		else//((data3 >= data1 && data3 <= data2) || (data3 >= data2 && data3 <= data1))
			mid_data <= data3;
			
		//ge the min value
		if(data1 <= data2 && data1 <= data3)
			min_data <= data1;
		else if(data2 <= data1 && data2 <= data3)
			min_data <= data2;
		else//(data3 <= data1 && data3 <= data2)
			min_data <= data3;
	end
end

endmodule
module Image_XYCrop(
	input			clk,				
	input			rst_n,				
	
	//CMOS 
	input			image_in_vsync,		
	input			image_in_href,		
	input		   	image_in_data,

	output			image_out_vsync,	
	output			image_out_href_left,	
	output		   	image_out_data_left,
    output			image_out_href_right,                                    	
    output		   	image_out_data_right                                       	
);

//-----------------------------------
reg		image_in_href_r  = 0;
reg		image_in_vsync_r = 0;
reg	   	image_in_data_r  = 0;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		image_in_vsync_r <= 0;
		image_in_href_r <= 0;
		image_in_data_r <= 0;
	end
	else begin
		image_in_vsync_r <= image_in_vsync;
		image_in_href_r <= image_in_href;
		image_in_data_r <= image_in_data;
	end
end
//-----------------------------------
//Image Ysize Crop
reg	 [11:0] image_ypos = 0;
wire image_in_href_negedge = (image_in_href_r & ~image_in_href) ? 1'b1 : 1'b0;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		image_ypos <= 0;
	else if(image_in_vsync == 1'b1) begin
		if(image_in_href_negedge == 1'b1)   //行同步信号的下降沿，一行信号赋值完成后，image_ypos累加1
			image_ypos <= image_ypos + 1'b1;
		else
			image_ypos <= image_ypos;
	end
	else
		image_ypos <= 0;
end
assign	image_out_vsync = image_in_vsync_r; // image_out_vsync是打一拍后的 image_in_vsync的信号，延时了一个时钟周期
			   
//-----------------------------------
//Image Hsize Crop
reg	[11:0] image_xpos = 0;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		image_xpos <= 0;
	else if(image_in_href == 1'b1)
		image_xpos <= image_xpos + 1'b1;
	else
		image_xpos <= 0;
end

assign	image_out_href_right = ((image_in_href_r == 1'b1) && (image_xpos > 10'd640) && (image_xpos < 12'd1280)) ? 1'b1 : 1'b0;
assign	image_out_data_right = (image_out_vsync & image_out_href_right) ? image_in_data_r : 1'd0;				   
assign	image_out_href_left  = ((image_in_href_r == 1'b1) && (image_xpos <= 10'd640)) ? 1'b1 : 1'b0;	 
assign	image_out_data_left  = (image_out_vsync & image_out_href_left)  ? image_in_data_r : 1'd0;

endmodule
module	Median_Filter_3X3 (
	input			    clk,
	input			    rst_n,

	input		[7:0]	data11, data12, data13,
	input		[7:0]	data21, data22, data23,
	input		[7:0]	data31, data32, data33,
	
	output		[7:0]	target_data
);

//--------------------------------------------------------------------------------------
//FPGA Median Filter Sort order
//	  	   Pixel				 Sort1					  Sort2				 Sort3
//	[   P1  P2   P3 ]	[   Max1  Mid1   Min1 ]	
//	[   P4  P5   P6 ]	[   Max2  Mid2   Min2 ]	[Max_min, Mid_mid, Min_max]	mid_valid
//	[   P7  P8   P9 ]	[   Max3  Mid3   Min3 ]

//Step1
wire	[7:0]	max_data1, mid_data1, min_data1;
Sort3	u_Sort3_1 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(data11), 
	.data2		(data12), 
	.data3		(data13),
	
	.max_data	(max_data1),
	.mid_data	(mid_data1),
	.min_data   (min_data1)
);

wire	[7:0]	max_data2, mid_data2, min_data2;
Sort3	u_Sort3_2 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(data21), 
	.data2		(data22), 
	.data3		(data23),
	
	.max_data	(max_data2),
	.mid_data	(mid_data2),
	.min_data   (min_data2)
);

wire	[7:0]	max_data3, mid_data3, min_data3;
Sort3	u_Sort3_3 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(data31), 
	.data2		(data32), 
	.data3		(data33),
	
	.max_data	(max_data3),
	.mid_data	(mid_data3),
	.min_data	(min_data3)
);

//Step2
wire	[7:0]	max_min_data, mid_mid_data, min_max_data;
Sort3	u_Sort3_4 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(max_data1), 
	.data2		(max_data2), 
	.data3		(max_data3),
	
	.max_data	(),
	.mid_data	(),
	.min_data   (max_min_data)
);

Sort3	u_Sort3_5 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(mid_data1), 
	.data2		(mid_data2), 
	.data3		(mid_data3),
	
	.max_data	(),
	.mid_data	(mid_mid_data),
	.min_data   ()
);

Sort3	u_Sort3_6 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(min_data1), 
	.data2		(min_data2), 
	.data3		(min_data3),
	
	.max_data	(min_max_data),
	.mid_data	(),
	.min_data   ()
);

//step3
Sort3	u_Sort3_7 (
	.clk		(clk),
	.rst_n		(rst_n),
	
	.data1		(max_min_data), 
	.data2		(mid_mid_data), 
	.data3		(min_max_data),
	
	.max_data	(),
	.mid_data	(target_data),
	.min_data   ()
);

endmodule
module Min_meas #
(
	parameter         data_width      = 4'd12,
	parameter         range_width     = 4'd10
)
(
	input				  clk_in,
	input 				  rst_n,
	input          [range_width-1:0]  range,
	input  signed  [data_width - 1:0] data_in,
	output signed  [data_width - 1:0] data_out
);

localparam 		  state_output    = 3'b010;
localparam 		  state_initial   = 3'b000;
localparam 		  state_detection = 3'b001;

reg signed [data_width - 1:0] data_out_buf  = 0;
reg signed [data_width - 1:0] data_out_buf1 = 0;
reg [2:0]  state = 3'b000;
reg 	   test_sig = 1'b0;
reg 	   test_sig_buf = 1'b0;
wire 	   test_done_sig = ~test_sig & test_sig_buf;
wire 	   test_start_sig = test_sig & ~test_sig_buf;

/***************************************************/
//define the time counter
reg [range_width-1:0] cnt0 = 1;

always@(posedge clk_in)
begin
	if (range == 0)
    begin
    	test_sig <= 1'b1;
    end
    else if (cnt0 == range)      
    begin
        cnt0 <= 10'd0;                    //count done,clearing the time counter
        test_sig <= 1'd0;
    end
    else
        test_sig <= 1'd1;                   //cnt0 counter = cnt0 counter + 1
        cnt0 <= cnt0 + 1'b1; 
end
/***************************************************/



always@(posedge clk_in)
begin
	if (range == 0)
	begin
		test_sig_buf <= 1'b0;
	end
	else
	begin
		test_sig_buf <= test_sig;
	end
end

always@(posedge clk_in or negedge rst_n)
begin
	if(!rst_n)
	begin
		data_out_buf <= 0;
		data_out_buf1 <= 0;
	end
	else
	begin
		case(state)
		state_initial:begin 
			if(test_start_sig) 
			begin 
				state <= state_detection; 
				data_out_buf <= 0;
			end 
			end
		state_detection:begin 
			if(test_done_sig)
				state <= state_output;
			else
				if(data_in > data_out_buf)
				begin
					data_out_buf <= data_in;
					if (range == 0)
					begin
						data_out_buf1 <= data_out_buf;
					end
				end
			end
		state_output:begin 
			data_out_buf1 <= data_out_buf;
			state <= state_initial; 
			end
		endcase
	end
end

assign data_out=data_out_buf1;

endmodule
module Fre_meas(
	input			  clk_in,	
	input			  square,
	input      [31:0] GATE_TIME,	
	output     [31:0] CNTCLK,		//闸门内系统时钟周期计数
	output     [31:0] CNTSQU		//闸门内待测方波时钟周期计数
);
//parameter   GATE_TIME = 28'd49_999_999;//实际闸门计数是99_999_999，仿真时设为10ms

reg		square_r0 = 1'b0;
reg		square_r1 = 1'b0;
reg		square_r2 = 1'b0;
reg		square_r3 = 1'b0;

reg		gate = 1'b0;	//闸门信号
reg		gatebuf = 1'b0; //与方波同步之后的闸门信号
reg		gatebuf1 = 1'b0;//同步闸门信号延时一拍

reg [31:0]	cnt1 = 28'd0;   //产生 1s 的闸门信号的计数器
reg	[31:0]	cnt2 = 28'd0;
reg	[31:0]	cnt2_r = 28'd0;
reg	[31:0]	cnt3 = 28'd0;
reg	[31:0]	cnt3_r = 28'd0;

wire		square_pose,square_nege;
wire		gate_start,gate_end;

//使方波和100MHz时钟同步并捕捉待测方波的边沿
always @ (posedge clk_in)
begin
	square_r0 <= square;
	square_r1 <= square_r0;//将外部输入的方波打两拍
	square_r2 <= square_r1;
	square_r3 <= square_r2;
end

assign square_pose = square_r2 & ~square_r3;
assign square_nege = ~square_r2 & square_r3;	

always @ (posedge clk_in)
begin
	if(cnt1 == GATE_TIME)begin
		cnt1 <= 28'd0;
		gate <= ~gate;//产生 1s 的闸门信号
		end
	else begin
		cnt1 <= cnt1 + 1'b1; 
		end
end

always @ (posedge clk_in )
begin
	if(square_pose == 1'b1)
	begin 
		gatebuf <= gate;//使闸门信号与待测方波同步，保证一个闸门包含整数个方波周期
	end
	gatebuf1 <= gatebuf;//将同步之后的闸门信号打一拍，用于捕捉闸门信号的边沿
end

assign	gate_start = gatebuf & ~gatebuf1;//表示闸门开始时刻
assign	gate_end = ~gatebuf & gatebuf1;//闸门结束时刻

//计数系统时钟周期
always @ (posedge clk_in)
begin
	if(gate_start == 1'b1) begin
		cnt2 <= 28'd1;
		end
	else if(gate_end == 1'b1) begin
		cnt2_r <= cnt2;//将所得结果保存在cnt2_r中，并将计数器清零
		cnt2 <= 28'd0;
		end
	else if(gatebuf1 == 1'b1) begin//在闸门内计数系统时钟周期
		cnt2 <= cnt2 + 1'b1;end
end

//计数待测方波周期数
always @ (posedge clk_in )
begin
	if(gate_start == 1'b1) begin 
		cnt3 <= 28'd0;
		end
	else if(gate_end == 1'b1) begin 
		cnt3_r <= cnt3;//将所得结果保存在cnt3_r中，并将计数器清零
		cnt3 <= 28'd0;
		end
	else if(gatebuf1 == 1'b1 && square_nege == 1'b1) begin//在闸门内计数待测方波周期数(数闸门内方波的下降沿）
		cnt3 <= cnt3 + 1'b1;
		end
end


assign CNTCLK = cnt2_r;
assign CNTSQU = cnt3_r;

endmodule
module measure
(
    input           clk_sys,
    input           clk_samp,
    input           rst_n,
    input           mearsure_start,
    input [11:0]    AD_data,
    output          measure_done_q,
    output [21:0]   data_out
);
parameter           cnt_clear = 22'd255;
reg                 clk_samp_buf0;
reg                 clk_samp_buf1;
wire                clk_samp_impluse = clk_samp_buf0 & ~clk_samp_buf1;//采样脉冲信号
wire [21:0]         mult_data;
reg [16:0]          cnt;
reg [39:0]          sig_energy;
reg [21:0]          data_out_buf;
reg                 measure_en;
wire                measure_done  = (cnt == cnt_clear) ? 1'b1:1'b0;
assign              measure_done_q = measure_done;
always@(posedge clk_sys)
begin
    clk_samp_buf0 <= clk_samp;
    clk_samp_buf1 <= clk_samp_buf0;
end
always@(posedge clk_sys)
begin
    if(!rst_n)
    begin
        measure_en <= 1'b0;
    end
    else if(mearsure_start)
        measure_en <= 1'b1;
    else if(measure_done)
        measure_en <= 1'b0;
    else
        measure_en <= measure_en;
end
always@(posedge clk_sys)
begin
    if(!rst_n)
    begin
        sig_energy <= 40'd0;
        cnt <= 17'd0;
        data_out_buf <= 22'd0;
    end
    else if(cnt == cnt_clear)
    begin
        sig_energy <= 40'd0;
        data_out_buf <= sig_energy[39:8];
        cnt <= 17'd0;
    end
    else if(clk_samp_impluse && measure_en)
    begin
        cnt <= cnt + 17'd1;
        sig_energy <= sig_energy + mult_data;
    end
    else
    begin
        sig_energy <= sig_energy;
        data_out_buf <= data_out_buf;
        cnt <= cnt;
    end
end
mult1 mult1_inst
(
.A(AD_data),
.B(AD_data),
.P(mult_data),
.CLK(clk_sys),
.CE(clk_samp_impluse)
);
assign data_out  = data_out_buf;
endmodule
module Max_meas #
(
	parameter         data_width      = 4'd12,
	parameter         range_width     = 4'd10
)
(
	input				  clk_in,
	input 				  rst_n,
	input          [range_width-1:0]  range,
	input  signed  [data_width - 1:0] data_in,
	output signed  [data_width - 1:0] data_out
);

localparam 		  state_output    = 3'b010;
localparam 		  state_initial   = 3'b000;
localparam 		  state_detection = 3'b001;

reg signed [data_width - 1:0] data_out_buf  = 0;
reg signed [data_width - 1:0] data_out_buf1 = 0;
reg [2:0]  state = 3'b000;
reg 	   test_sig = 1'b0;
reg 	   test_sig_buf = 1'b0;
wire 	   test_done_sig = ~test_sig & test_sig_buf;
wire 	   test_start_sig = test_sig & ~test_sig_buf;

/***************************************************/
//define the time counter
reg [range_width-1:0] cnt0 = 1;

always@(posedge clk_in)
begin
	if (range == 0)
    begin
    	test_sig <= 1'b1;
    end
    else if (cnt0 == range)      
    begin
        cnt0 <= 10'd0;                    //count done,clearing the time counter
        test_sig <= 1'd0;
    end
    else
        test_sig <= 1'd1;                   //cnt0 counter = cnt0 counter + 1
        cnt0 <= cnt0 + 1'b1; 
end
/***************************************************/



always@(posedge clk_in)
begin
	if (range == 0)
	begin
		test_sig_buf <= 1'b0;
	end
	else
	begin
		test_sig_buf <= test_sig;
	end
end

always@(posedge clk_in or negedge rst_n)
begin
	if(!rst_n)
	begin
		data_out_buf <= 0;
		data_out_buf1 <= 0;
	end
	else
	begin
		case(state)
		state_initial:begin 
			if(test_start_sig) 
			begin 
				state <= state_detection; 
				data_out_buf <= 0;
			end 
			end
		state_detection:begin 
			if(test_done_sig)
				state <= state_output;
			else
				if(data_in > data_out_buf)
				begin
					data_out_buf <= data_in;
					if (range == 0)
					begin
						data_out_buf1 <= data_out_buf;
					end
				end
			end
		state_output:begin 
			data_out_buf1 <= data_out_buf;
			state <= state_initial; 
			end
		endcase
	end
end

assign data_out=data_out_buf1;

endmodule