dakies/OSS_Verilog huggingface dataset:
module decoder (
  input [15:0] instr,
  input [2:0]  sideset_bits,
  input        sideset_enable_bit,
  output [2:0] op,
  output [2:0] op1,
  output [4:0] op2,
  output [4:0] delay,
  output [4:0] side_set,
  output       sideset_enabled
);

  wire [2:0] delay_bits = 5 - sideset_bits;

  assign op = instr[15:13];
  assign op1 = instr[7:5];
  assign op2 = instr[4:0];
  assign delay = (instr[12:8] << sideset_bits) >> sideset_bits;
  assign side_set = instr[12:8] << sideset_enable_bit >> sideset_enable_bit + delay_bits;
  assign sideset_enabled = sideset_enable_bit ? instr[12] : 1;

endmodule
module scratch (
  input         clk,
  input         penable,
  input         reset,
  input         stalled,
  input [31:0]  din,
  input         set,
  input         dec,
  output [31:0] dout
);

  reg [31:0] val;

  assign dout = val;

  always @(posedge clk) begin
    if (reset)
      val <= 0;
    else if (penable && !stalled) begin
      if (set)
        val <= din;
      else if (dec)
        val <= val - 1;
    end
  end

endmodule
module divider (
  input         clk,
  input         reset,
  input [23:0]  div,
  input         use_divider,
  output        penable,
  output        pclk
);

  reg [23:0] div_counter;
  reg        pen;
  reg        old_pen;

  always @(posedge clk) begin
    if (reset) begin
      div_counter <= 0;
      pen <= 1;
      old_pen <= 0;
    end else begin
      if (use_divider) begin
        old_pen <= pen;
        div_counter <= div_counter + 256;
        if (div_counter >= div - 256)
          div_counter <= div_counter - (div - 256);
        pen <= div_counter < (div >> 1);
      end
    end
  end

  assign penable = pen & ~old_pen;
  assign pclk = pen;

endmodule
module isr (
  input         clk,
  input         penable,
  input         reset,
  input         stalled,
  input [31:0]  din,
  input [4:0]   shift,
  input         dir,
  input         set,
  input         do_shift,
  input [5:0]   bit_count,
  output [31:0] dout,
  output [5:0]  shift_count
);

  reg [31:0] shift_reg;
  reg [5:0]  count;

  // A shift value of 0 means shift 32
  wire [5:0] shift_val = shift == 0 ? 32 : shift;
  // Left align the input value and concatenate it with the shift register to produce a 64-bit value
  wire [63:0] new_shift = dir ? {din, shift_reg} >> shift_val
                              : {shift_reg, din << (32 - shift_val)} << shift_val;

  always @(posedge clk) begin
    if (reset) begin
      shift_reg <= 0;
      count <= 0;  // Empty
    end else if (penable && !stalled) begin
       if (set) begin
         shift_reg <= din;
         count <= bit_count;
       end else if (do_shift) begin
         shift_reg <= dir ? new_shift[31:0] : new_shift[63:32];
         count <= count + shift_val > 32 ? 32 : count + shift_val;
       end
    end
  end

  assign dout = shift_reg;
  assign shift_count = count;

endmodule
module clk_mmcm(clk_200, reset, locked, clk_in1)
/* synthesis syn_black_box black_box_pad_pin="clk_200,reset,locked,clk_in1" */;
  output clk_200;
  input reset;
  output locked;
  input clk_in1;
endmodule
module clk_mmcm 
 (
  // Clock out ports
  output        clk_200,
  // Status and control signals
  input         reset,
  output        locked,
 // Clock in ports
  input         clk_in1
 );

  clk_mmcm_clk_wiz inst
  (
  // Clock out ports  
  .clk_200(clk_200),
  // Status and control signals               
  .reset(reset), 
  .locked(locked),
 // Clock in ports
  .clk_in1(clk_in1)
  );

endmodule
module ddr3_controller(ddr3_dq, ddr3_dqs_n, ddr3_dqs_p, ddr3_addr, 
  ddr3_ba, ddr3_ras_n, ddr3_cas_n, ddr3_we_n, ddr3_reset_n, ddr3_ck_p, ddr3_ck_n, ddr3_cke, 
  ddr3_cs_n, ddr3_dm, ddr3_odt, sys_clk_i, app_addr, app_cmd, app_en, app_wdf_data, app_wdf_end, 
  app_wdf_mask, app_wdf_wren, app_rd_data, app_rd_data_end, app_rd_data_valid, app_rdy, 
  app_wdf_rdy, app_sr_req, app_ref_req, app_zq_req, app_sr_active, app_ref_ack, app_zq_ack, 
  ui_clk, ui_clk_sync_rst, init_calib_complete, device_temp, sys_rst)
/* synthesis syn_black_box black_box_pad_pin="ddr3_dq[15:0],ddr3_dqs_n[1:0],ddr3_dqs_p[1:0],ddr3_addr[13:0],ddr3_ba[2:0],ddr3_ras_n,ddr3_cas_n,ddr3_we_n,ddr3_reset_n,ddr3_ck_p[0:0],ddr3_ck_n[0:0],ddr3_cke[0:0],ddr3_cs_n[0:0],ddr3_dm[1:0],ddr3_odt[0:0],sys_clk_i,app_addr[27:0],app_cmd[2:0],app_en,app_wdf_data[127:0],app_wdf_end,app_wdf_mask[15:0],app_wdf_wren,app_rd_data[127:0],app_rd_data_end,app_rd_data_valid,app_rdy,app_wdf_rdy,app_sr_req,app_ref_req,app_zq_req,app_sr_active,app_ref_ack,app_zq_ack,ui_clk,ui_clk_sync_rst,init_calib_complete,device_temp[11:0],sys_rst" */;
  inout [15:0]ddr3_dq;
  inout [1:0]ddr3_dqs_n;
  inout [1:0]ddr3_dqs_p;
  output [13:0]ddr3_addr;
  output [2:0]ddr3_ba;
  output ddr3_ras_n;
  output ddr3_cas_n;
  output ddr3_we_n;
  output ddr3_reset_n;
  output [0:0]ddr3_ck_p;
  output [0:0]ddr3_ck_n;
  output [0:0]ddr3_cke;
  output [0:0]ddr3_cs_n;
  output [1:0]ddr3_dm;
  output [0:0]ddr3_odt;
  input sys_clk_i;
  input [27:0]app_addr;
  input [2:0]app_cmd;
  input app_en;
  input [127:0]app_wdf_data;
  input app_wdf_end;
  input [15:0]app_wdf_mask;
  input app_wdf_wren;
  output [127:0]app_rd_data;
  output app_rd_data_end;
  output app_rd_data_valid;
  output app_rdy;
  output app_wdf_rdy;
  input app_sr_req;
  input app_ref_req;
  input app_zq_req;
  output app_sr_active;
  output app_ref_ack;
  output app_zq_ack;
  output ui_clk;
  output ui_clk_sync_rst;
  output init_calib_complete;
  output [11:0]device_temp;
  input sys_rst;
endmodule
module mig_7series_v4_2_data_prbs_gen #
  (
    parameter TCQ           = 100,

    parameter EYE_TEST   = "FALSE",
    parameter PRBS_WIDTH = 32,                                                                       // "SEQUENTIAL_BUrst_i"
    parameter SEED_WIDTH = 32    
   )
  (
   input           clk_i,
   input           clk_en,
   input           rst_i,
   input           prbs_seed_init,  // when high the prbs_x_seed will be loaded
   input [PRBS_WIDTH - 1:0]  prbs_seed_i,
   
   output  [PRBS_WIDTH - 1:0]  prbs_o     // generated address
  );
  
reg [PRBS_WIDTH - 1 :0] prbs;  
reg [PRBS_WIDTH :1] lfsr_q;
integer i;



always @ (posedge clk_i)
begin
   if (prbs_seed_init && EYE_TEST == "FALSE"  || rst_i )  //reset it to a known good state to prevent it locks up
//   if (rst_i )  //reset it to a known good state to prevent it locks up

      begin
        lfsr_q[4:1] <= #TCQ   prbs_seed_i[3:0] | 4'h5;
       // lfsr_q[PRBS_WIDTH-1:4] <= #TCQ  prbs_seed_i[PRBS_WIDTH-1:4] ;
         
        lfsr_q[PRBS_WIDTH:5] <= #TCQ  prbs_seed_i[PRBS_WIDTH-1:4] ;
      end
   else   if (clk_en) begin
     
        lfsr_q[32:9] <= #TCQ  lfsr_q[31:8];
        lfsr_q[8]    <= #TCQ  lfsr_q[32] ^ lfsr_q[7];
        lfsr_q[7]    <= #TCQ  lfsr_q[32] ^ lfsr_q[6];
        lfsr_q[6:4]  <= #TCQ  lfsr_q[5:3];
        
        lfsr_q[3]    <= #TCQ  lfsr_q[32] ^ lfsr_q[2];
        lfsr_q[2]    <= #TCQ  lfsr_q[1] ;
        lfsr_q[1]    <= #TCQ  lfsr_q[32];
       
        
         end
end
 
always @ (lfsr_q[PRBS_WIDTH:1]) begin
       prbs = lfsr_q[PRBS_WIDTH:1];
end

assign prbs_o = prbs;

endmodule
module mig_7series_v4_2_tg_status #(
   parameter TCQ           = 100,  

   parameter DWIDTH = 32
    )
    (
      
   
   input                            clk_i  ,        
   input                            rst_i ,
   input                            manual_clear_error,
   input                            data_error_i ,  
   input [DWIDTH-1:0]               cmp_data_i,     
   input [DWIDTH-1:0]               rd_data_i ,     
   input [31:0]                     cmp_addr_i ,    
   input [5:0]                      cmp_bl_i ,      
   input                            mcb_cmd_full_i ,
   input                            mcb_wr_full_i,  
   input                            mcb_rd_empty_i, 
   output reg [64 + (2*DWIDTH - 1):0]   error_status,   
   output                           error                  
  );

reg data_error_r;
reg error_set;
assign  error = error_set;

always @ (posedge clk_i)
    data_error_r <= #TCQ  data_error_i;

always @ (posedge clk_i)
begin

if (rst_i || manual_clear_error) begin
   error_status <= #TCQ  'b0;
   error_set    <= #TCQ  1'b0;
end
else begin
  // latch the first error only
  if (data_error_i && ~data_error_r && ~error_set ) begin
     error_status[31:0]  <= #TCQ  cmp_addr_i;
     error_status[37:32] <= #TCQ  cmp_bl_i;
     error_status[40] <= #TCQ  mcb_cmd_full_i;
     error_status[41] <= #TCQ  mcb_wr_full_i;
     error_status[42] <= #TCQ  mcb_rd_empty_i;
     error_set <= #TCQ  1'b1;
     error_status[64 + (DWIDTH - 1)  :64]           <= #TCQ  cmp_data_i;
     error_status[64 + (2*DWIDTH - 1):64 + DWIDTH]  <= #TCQ  rd_data_i;
   
  end

  error_status[39:38]  <= #TCQ  'b0;    // reserved
  error_status[63:43] <= #TCQ  'b0;    // reserved


end end
    
endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [9:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output              rsp_valid,
  input               rsp_ready,
  output     [31:0]   rsp_payload_outputs_0,
  input               clk,
  input               reset
);

  assign rsp_valid = cmd_valid;
  assign cmd_ready = rsp_ready;

  //  byte sum (unsigned)
  wire [31:0] cfu0;
  assign cfu0[31:0] =  cmd_payload_inputs_0[7:0]   + cmd_payload_inputs_1[7:0] +
                       cmd_payload_inputs_0[15:8]  + cmd_payload_inputs_1[15:8] +
                       cmd_payload_inputs_0[23:16] + cmd_payload_inputs_1[23:16] +
                       cmd_payload_inputs_0[31:24] + cmd_payload_inputs_1[31:24];

  // byte swap
  wire [31:0] cfu1;
  assign cfu1[31:24] =     cmd_payload_inputs_0[7:0];
  assign cfu1[23:16] =     cmd_payload_inputs_0[15:8];
  assign cfu1[15:8] =      cmd_payload_inputs_0[23:16];
  assign cfu1[7:0] =       cmd_payload_inputs_0[31:24];

  // bit reverse
  wire [31:0] cfu2;
  genvar n;
  generate
      for (n=0; n<32; n=n+1) begin
          assign cfu2[n] =     cmd_payload_inputs_0[31-n];
      end
  endgenerate


  //
  // select output -- note that we're not fully decoding the 3 function_id bits
  //
  assign rsp_payload_outputs_0 = cmd_payload_function_id[1] ? cfu2 :
                                      ( cmd_payload_function_id[0] ? cfu1 : cfu0);


endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [9:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output              rsp_valid,
  input               rsp_ready,
  output     [31:0]   rsp_payload_outputs_0,
  input               reset,
  input               clk
);

  // Trivial handshaking for a combinational CFU
  assign rsp_valid = cmd_valid;
  assign cmd_ready = rsp_ready;


  wire [31:0] mul    = $signed(cmd_payload_inputs_0) * $signed(cmd_payload_inputs_1);

  wire [31:0] mulsh  = $signed(mul) >>> 10;

  assign rsp_payload_outputs_0 = cmd_payload_function_id[0] ? mul : mulsh;


endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [9:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output              rsp_valid,
  input               rsp_ready,
  output     [31:0]   rsp_payload_outputs_0,
  input               reset,
  input               clk
);

  // Trivial handshaking for a combinational CFU
  assign rsp_valid = cmd_valid;
  assign cmd_ready = rsp_ready;

  //
  // select output -- note that we're not fully decoding the 3 function_id bits
  //
  assign rsp_payload_outputs_0 = cmd_payload_function_id[0] ? 
                                           cmd_payload_inputs_1 :
                                           cmd_payload_inputs_0 ;


endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [9:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output              rsp_valid,
  input               rsp_ready,
  output     [31:0]   rsp_payload_outputs_0,
  input               reset,
  input               clk
);

  // Trivial handshaking for a combinational CFU
  assign rsp_valid = cmd_valid;
  assign cmd_ready = rsp_ready;

  //
  // select output -- note that we're not fully decoding the 3 function_id bits
  //
  assign rsp_payload_outputs_0 = ~cmd_payload_inputs_0 ^ cmd_payload_inputs_1;


endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [9:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output reg          rsp_valid,
  input               rsp_ready,
  output reg [31:0]   rsp_payload_outputs_0,
  input               reset,
  input               clk
);
  localparam InputOffset = $signed(9'd128);

  // SIMD multiply step:
  wire signed [15:0] prod_0, prod_1, prod_2, prod_3;
  assign prod_0 =  ($signed(cmd_payload_inputs_0[7 : 0]) + InputOffset)
                  * $signed(cmd_payload_inputs_1[7 : 0]);
  assign prod_1 =  ($signed(cmd_payload_inputs_0[15: 8]) + InputOffset)
                  * $signed(cmd_payload_inputs_1[15: 8]);
  assign prod_2 =  ($signed(cmd_payload_inputs_0[23:16]) + InputOffset)
                  * $signed(cmd_payload_inputs_1[23:16]);
  assign prod_3 =  ($signed(cmd_payload_inputs_0[31:24]) + InputOffset)
                  * $signed(cmd_payload_inputs_1[31:24]);

  wire signed [31:0] sum_prods;
  assign sum_prods = prod_0 + prod_1 + prod_2 + prod_3;

  // Only not ready for a command when we have a response.
  assign cmd_ready = ~rsp_valid;

  always @(posedge clk) begin
    if (reset) begin
      rsp_payload_outputs_0 <= 32'b0;
      rsp_valid <= 1'b0;
    end else if (rsp_valid) begin
      // Waiting to hand off response to CPU.
      rsp_valid <= ~rsp_ready;
    end else if (cmd_valid) begin
      rsp_valid <= 1'b1;
      // Accumulate step:
      rsp_payload_outputs_0 <= |cmd_payload_function_id[9:3]
          ? 32'b0
          : rsp_payload_outputs_0 + sum_prods;
    end
  end
endmodule
module Cfu (
  input               cmd_valid,
  output              cmd_ready,
  input      [2:0]    cmd_payload_function_id,
  input      [31:0]   cmd_payload_inputs_0,
  input      [31:0]   cmd_payload_inputs_1,
  output              rsp_valid,
  input               rsp_ready,
  output     [31:0]   rsp_payload_outputs_0,
  input               clk,
  input               reset
);

  assign rsp_valid = cmd_valid;
  assign cmd_ready = rsp_ready;

  //  byte sum (unsigned)
  wire [31:0] cfu0;
  assign cfu0[31:0] =  cmd_payload_inputs_0[7:0]   + cmd_payload_inputs_1[7:0] +
                       cmd_payload_inputs_0[15:8]  + cmd_payload_inputs_1[15:8] +
                       cmd_payload_inputs_0[23:16] + cmd_payload_inputs_1[23:16] +
                       cmd_payload_inputs_0[31:24] + cmd_payload_inputs_1[31:24];

  // byte swap
  wire [31:0] cfu1;
  assign cfu1[31:24] =     cmd_payload_inputs_0[7:0];
  assign cfu1[23:16] =     cmd_payload_inputs_0[15:8];
  assign cfu1[15:8] =      cmd_payload_inputs_0[23:16];
  assign cfu1[7:0] =       cmd_payload_inputs_0[31:24];

  // bit reverse
  wire [31:0] cfu2;
  genvar n;
  generate
      for (n=0; n<32; n=n+1) begin
          assign cfu2[n] =     cmd_payload_inputs_0[31-n];
      end
  endgenerate


  // select output
  assign rsp_payload_outputs_0 = cmd_payload_function_id[1] ? cfu2 :
                                      ( cmd_payload_function_id[0] ? cfu1 : cfu0);


endmodule
module depth_split (we, addr, datain, dataout, clk);

    input we; 
    input[11 - 1:0] addr; 
    input[2 - 1:0] datain; 
    output[2 - 1:0] dataout; 
    wire[2 - 1:0] dataout;
    input clk; 




single_port_ram new_ram(
  .clk (clk),
  .we(we),
  .data(datain),
  .out(dataout),
  .addr(addr)
  );
  
  
endmodule
module accum (clock, reset_n, D, Q);
input clock, reset_n;
input  [3:0] D;
output [3:0] Q;
reg    [3:0] tmp; 


  always @(posedge clock)
    begin
      if (reset_n)
        tmp <= 4'b0000;
      else
        tmp <= tmp + D;
    end
assign Q = tmp;
endmodule
module  simple(clock,
                enable,
                value_out
                );

input   clock;
input   enable;
reg temp;
output value_out;

always @(posedge clock)
begin
	if (enable == 1'b1) begin
		temp <= 1'b0;
	end
end

assign value_out = temp;

endmodule
module simple_comp
(
    a_in, b_in, c_in,
    d_out,
    clock, rst
);

    input [15:0] a_in;
    input [15:0] b_in;
    input [15:0] c_in;

    input clock;
    input rst;

    output [15:0] d_out;

    reg [15:0] sum_c;
    reg [15:0] sum_d;

    always @ (posedge clock)
        if(rst)
            sum_c <= 16'b0;
        else
            sum_c <= a_in + b_in;

    always @ (posedge clock)
        if(rst)
            sum_d <= 16'b0;
        else
            sum_d <= sum_c + c_in;

    assign d_out = sum_d;

endmodule
module counter
(
    d_out, clock, rst, d_en
);

    input clock;
    input rst;
    input d_en;
    output [11:0] d_out;

    reg [11:0] counter;

    always @ (posedge clock)
        if(rst)
        begin
            counter <= 12'b0;
        end
        else if(d_en)
        begin
            counter <= counter + 1'b1;
        end
        else
        begin
            counter <= counter;
        end

    assign d_out = counter;

endmodule
module inv_shift_reg
(
    din,
    dout,
    clock,
    rst
);

    input din;
    output dout;

    input clock;
    input rst;

    reg [31:0] s_reg;

    always @ (posedge clock)
        if(rst)
            s_reg <= 32'b0;
        else
            begin
                s_reg[31:1] <= s_reg[30:0];
                s_reg[0] <= din;
            end

    assign dout = s_reg[31];

endmodule
module wide_inv_reg
(
    d_in,
    d_out,
    clock,
    rst
);
    input clock;
    input rst;
    input [31:0] d_in;

    reg [31:0] d_d;

    output [31:0] d_out;

    always @ (posedge clock)
        if(rst)
            d_d <= 32'b0;
        else
            d_d <= ~d_in;

    assign d_out = d_d;

endmodule
module memory_controller
(
	clk,
	memory_controller_address,
	memory_controller_write_enable,
	memory_controller_in,
	memory_controller_out
);
input clk;
input [`MEMORY_CONTROLLER_ADDR_SIZE-1:0] memory_controller_address;
input memory_controller_write_enable;
input [`MEMORY_CONTROLLER_DATA_SIZE-1:0] memory_controller_in;
output  [`MEMORY_CONTROLLER_DATA_SIZE-1:0] memory_controller_out;
reg [`MEMORY_CONTROLLER_DATA_SIZE-1:0] memory_controller_out;


reg [4:0] str_address;
reg str_write_enable;
reg [7:0] str_in;
wire [7:0] str_out;

single_port_ram _str (
	.clk( clk ),
	.addr( str_address ),
	.we( str_write_enable ),
	.data( str_in ),
	.out( str_out )
);


wire  tag;

//must use all wires inside module.....
assign tag = |memory_controller_address & |memory_controller_address & | memory_controller_in;
reg [`MEMORY_CONTROLLER_TAG_SIZE-1:0] prevTag;
always @(posedge clk)
	prevTag <= tag;
always @( tag or memory_controller_address or memory_controller_write_enable or memory_controller_in)
begin

case(tag)

	1'b0:
	begin
		str_address = memory_controller_address[5-1+0:0];
		str_write_enable = memory_controller_write_enable;
		str_in[8-1:0] = memory_controller_in[8-1:0];
	end
endcase

case(prevTag)

	1'b0:
		memory_controller_out = str_out;
endcase
end

endmodule
module single_inv_reg
(
    d_in,
    d_out,
    clock,
    rst
);
    input clock;
    input rst;
    input d_in;

    reg d_d;

    output d_out;

    always @ (posedge clock)
        if(rst)
            d_d <= 1'b0;
        else
            d_d <= ~d_in;


    assign d_out = d_d;

endmodule
module wide_inv
(
    d_in,
    d_out,
    clock,
    rst
);
    input clock;
    input rst;
    input [31:0] d_in;

    output [31:0] d_out;

    assign d_out = ~d_in;

endmodule
module single_inv
(
    d_in,
    d_out,
    clock,
    rst
);

    input clock;
    input rst;
    input d_in;

    output d_out;

    assign d_out = ~d_in;

endmodule
module multi_consumer
(
    d_in,
    d_out_1, d_out_2, d_out_4, d_out_7,
    clock, rst
);

    input clock;
    input rst;

    input [15:0] d_in;

    output [15:0] d_out_1, d_out_2, d_out_4, d_out_7;

    assign d_out_1 = d_in + 1'b1;
    assign d_out_2 = d_in + 2'b10;
    assign d_out_4 = d_in + 3'b100;
    assign d_out_7 = d_in + 3'b111;
    
endmodule
module ff_en
(
    d_in, d_out, clock, rst, d_en
);
    input clock;
    input rst;
    input d_en;
    
    input [9:0] d_in;
    output [9:0] d_out;

    reg [9:0] ff_d;

    assign d_out = ff_d;

    always @ (posedge clock)
        if(rst)
            ff_d <= 10'b0;
        else if(d_en)
            ff_d <= d_in;
        else
            ff_d <= ff_d;

endmodule
module dcounter
(
    d_out, clock, rst, d_en
);

    input clock;
    input rst;
    input d_en;
    output [15:0] d_out;

    reg [15:0] counter;

    always @ (posedge clock)
        if(rst)
        begin
            counter <= 16'b0;
        end
        else if(d_en)
        begin
            counter <= counter - 1'b1;
        end
        else
        begin
            counter <= counter;
        end

    assign d_out = counter;

endmodule
module counter
(
    d_out, clock, rst, d_en
);

    input clock;
    input rst;
    input d_en;
    output [63:0] d_out;

    reg [63:0] counter;

    always @ (posedge clock)
        if(rst)
        begin
            counter <= 64'b0;
        end
        else if(d_en)
        begin
            counter <= counter + 1'b1;
        end
        else
        begin
            counter <= counter;
        end

    assign d_out = counter;

endmodule
module 	bfly(clock, 
		reset,
		re_w, 
		re_x, 
		re_y,
		im_w,
		im_x,
		im_y, 
		re_z,
		im_z
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;

input [`BITS-1:0] re_w;
input [`BITS-1:0] re_x;
input [`BITS-1:0] re_y;
input [`BITS-1:0] im_w;
input [`BITS-1:0] im_x;
input [`BITS-1:0] im_y;

output [`BITS-1:0] re_z;
output [`BITS-1:0] im_z;


wire [`BITS-1:0]	x1;
wire [`BITS-1:0]	x2;
wire [`BITS-1:0]	x3;
wire [`BITS-1:0]	x4;

wire [`BITS-1:0]	sub5;
wire [`BITS-1:0]	add6;
wire [`BITS-1:0]	re_z;
wire [`BITS-1:0]	im_z;

reg [`BITS-1:0] re_y_reg1;

reg [`BITS-1:0] re_y_reg2;
reg [`BITS-1:0] re_y_reg3;
reg [`BITS-1:0] re_y_reg4;
reg [`BITS-1:0] re_y_reg5;
reg [`BITS-1:0] re_y_reg6;


reg [`BITS-1:0] im_y_reg1;

reg [`BITS-1:0] im_y_reg2;
reg [`BITS-1:0] im_y_reg3;
reg [`BITS-1:0] im_y_reg4;
reg [`BITS-1:0] im_y_reg5;
reg [`BITS-1:0] im_y_reg6;



//assign	x1 = re_x * re_w;
wire [7:0] x1_control;
fpu_mul x1_mul
( 
	.clk(clock), 
	.opa(re_x), 
	.opb(re_w), 
	.out(x1), 
	.control(x1_control) 
);

//assign	x2 = im_x * im_w;
wire [7:0] x2_control;
fpu_mul x2_mul
( 
	.clk(clock), 
	.opa(im_x), 
	.opb(im_w), 
	.out(x2), 
	.control(x2_control) 
);


//assign	x3 = re_x * im_w;
wire [7:0] x3_control;
fpu_mul x3_mul
( 
	.clk(clock), 
	.opa(re_x), 
	.opb(im_w), 
	.out(x3), 
	.control(x3_control) 
);

//assign	x4 = im_x * re_w;
wire [7:0] x4_control;
fpu_mul x4_mul
( 
	.clk(clock), 
	.opa(im_x), 
	.opb(re_w), 
	.out(x4), 
	.control(x4_control) 
);


//assign	sub5 = x1 - x2;
wire [7:0] sub5_control;
fpu_add sub5_add
( 
	.clk(clock), 
	.opa(x1), 
	.opb(x2), 
	.out(sub5), 
	.control(sub5_control) 
);

//assign	add6 = x3 + x4;
wire [7:0] add6_control;
fpu_add add6_add
( 
	.clk(clock), 
	.opa(x3), 
	.opb(x4), 
	.out(add6), 
	.control(add6_control) 
);

//assign	re_z = sub5 + re_y_reg1;
wire [7:0] re_z_control;
fpu_add re_z_add
( 
	.clk(clock), 
	.opa(sub5), 
	.opb(re_y_reg6), 
	.out(re_z), 
	.control(re_z_control) 
);


//assign 	im_z = add6 + im_y_reg1;
wire [7:0] im_z_control;
fpu_add im_z_add
( 
	.clk(clock), 
	.opa(add6), 
	.opb(im_y_reg6), 
	.out(im_z), 
	.control(im_z_control) 
);

always @(posedge clock)
begin
	re_y_reg1 <= re_y;

	re_y_reg2 <= re_y_reg1;
	re_y_reg3 <= re_y_reg2;
	re_y_reg4 <= re_y_reg3;
	re_y_reg5 <= re_y_reg4;
	re_y_reg6 <= re_y_reg5;

	im_y_reg1 <= im_y;

	im_y_reg2 <= im_y_reg1;	
	im_y_reg3 <= im_y_reg2;	
	im_y_reg4 <= im_y_reg3;	
	im_y_reg5 <= im_y_reg4;
	im_y_reg6 <= im_y_reg5;	

end

endmodule
module fifo(clock, fifo_in, fifo_out);
	input clock;
	input [`BITS-1:0] fifo_in;
	output [`BITS-1:0] fifo_out;
	wire [`BITS-1:0] fifo_out;

	reg [`BITS-1:0] freg1;

	reg [`BITS-1:0] freg2;
	reg [`BITS-1:0] freg3;
	reg [`BITS-1:0] freg4;
	reg [`BITS-1:0] freg5;
	reg [`BITS-1:0] freg6;
	reg [`BITS-1:0] freg7;
	reg [`BITS-1:0] freg8;
	reg [`BITS-1:0] freg9;
	reg [`BITS-1:0] freg10;
	reg [`BITS-1:0] freg11;
	reg [`BITS-1:0] freg12;
	reg [`BITS-1:0] freg13;
	reg [`BITS-1:0] freg14;
	reg [`BITS-1:0] freg15;
	reg [`BITS-1:0] freg16;
	reg [`BITS-1:0] freg17;
	reg [`BITS-1:0] freg18;
	reg [`BITS-1:0] freg19;
	reg [`BITS-1:0] freg20;
	reg [`BITS-1:0] freg21;
	reg [`BITS-1:0] freg22;
	reg [`BITS-1:0] freg23;
	reg [`BITS-1:0] freg24;
	reg [`BITS-1:0] freg25;
	reg [`BITS-1:0] freg26;
	reg [`BITS-1:0] freg27;
	reg [`BITS-1:0] freg28;
	reg [`BITS-1:0] freg29;
	reg [`BITS-1:0] freg30;
	reg [`BITS-1:0] freg31;
	reg [`BITS-1:0] freg32;
	reg [`BITS-1:0] freg33;
	reg [`BITS-1:0] freg34;
 
	assign fifo_out = freg34;

	always @(posedge clock)
	begin
		freg1 <= fifo_in;

		freg2 <= freg1;
		freg3 <= freg2;
		freg4 <= freg3;
		freg5 <= freg4;
		freg6 <= freg5;
		freg7 <= freg6;
		freg8 <= freg7;
		freg9 <= freg8;
		freg10 <= freg9;
		freg11 <= freg10;
		freg12 <= freg11;
		freg13 <= freg12;
		freg14 <= freg13;
		freg15 <= freg14;
		freg16 <= freg15;
		freg17 <= freg16;
		freg18 <= freg17;
		freg19 <= freg18;
		freg20 <= freg19;
		freg21 <= freg20;
		freg22 <= freg21;
		freg23 <= freg22;
		freg24 <= freg23;
		freg25 <= freg24;
		freg26 <= freg25;
		freg27 <= freg26;
		freg28 <= freg27;
		freg29 <= freg28;
		freg30 <= freg29;
		freg31 <= freg30;
		freg32 <= freg31;
		freg33 <= freg32;
		freg34 <= freg33;

	end
endmodule
module delay5 (clock, d5_delay_in, d5_delay_out);
	input clock;
	input [`BITS-1:0] d5_delay_in;
	output [`BITS-1:0] d5_delay_out;

	//FIFO delay
	reg [`BITS-1:0] d5_reg1;
/*
	reg [`BITS-1:0] d5_reg2;
	reg [`BITS-1:0] d5_reg3;
	reg [`BITS-1:0] d5_reg4;
	reg [`BITS-1:0] d5_reg5;
	reg [`BITS-1:0] d5_reg6;
*/

	assign d5_delay_out = d5_reg1;

	always @(posedge clock)
	begin
		d5_reg1 <= d5_delay_in;
/*
		d5_reg2 <= d5_reg1;
		d5_reg3 <= d5_reg2;
		d5_reg4 <= d5_reg3;
		d5_reg5 <= d5_reg4;
		d5_reg6 <= d5_reg5;
*/
	end
endmodule
module delay44 (clock, delay_in, delay_out);
	input clock;
	input [`BITS-1:0] delay_in;
	output [`BITS-1:0] delay_out;
//	wire [`BITS-1:0] delay_out;

	//FIFO delay
	wire [`BITS-1:0] fifo_out;
	
	//multiplier delay
 	wire [`BITS-1:0] delay5_dout1;

	//adder delay
 	wire [`BITS-1:0] delay5_dout2;

	fifo fifo_delay(clock, delay_in , fifo_out);
	delay5 delay_d1(clock, fifo_out, delay5_dout1);
	delay5 delay_d2(clock, delay5_dout1, delay5_dout2);

	assign delay_out = delay5_dout2;
//	always @(posedge clock)
//	begin
//		fifo_out <= delay_in;
//		delay5_dout1 <= fifo_out;
//		delay5_dout2 <= delay5_dout1;
//	end

endmodule
module delay_chain (clock, delay_in, delay_out);
	input clock;
	input [`BITS-1:0] delay_in;
	output [`BITS-1:0] delay_out;
//	wire [`BITS-1:0] delay_out;

	wire [`BITS-1:0] delay44_out;
	wire [`BITS-1:0] delay5_out1;
	wire [`BITS-1:0] delay5_out2;
	wire [`BITS-1:0] delay5_out3;
	wire [`BITS-1:0] delay5_out4;

	delay44 delay_c1(clock, delay_in, delay44_out);
	delay5 delay_c2(clock, delay44_out, delay5_out1);
	delay5 delay_c3(clock, delay5_out1, delay5_out2);
	delay5 delay_c4(clock, delay5_out2, delay5_out3);
	delay5 delay_c5(clock, delay5_out3, delay5_out4);

	assign delay_out = delay5_out4;
endmodule
module 	syn2(clock, 
		reset,
		in1,
		in2,
		in3, 
		in4,
		in5,
		out_1,
		out_2,
		out_3,
		out_4
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;

input [`BITS-1:0] in1;
input [`BITS-1:0] in2;
input [`BITS-1:0] in3;
input [`BITS-1:0] in4;
input [`BITS-1:0] in5;

output [`BITS-1:0] out_1;
output [`BITS-1:0] out_2;
output [`BITS-1:0] out_3;
output [`BITS-1:0] out_4;


wire [`BITS-1:0] x1;
wire [`BITS-1:0] x2;
wire [`BITS-1:0] x3;
wire [`BITS-1:0] x4;

wire [`BITS-1:0] add1;
wire [`BITS-1:0] add2;
wire [`BITS-1:0] add3;
wire [`BITS-1:0] add4;
wire [`BITS-1:0] add5;

reg [`BITS-1:0] reg1;
reg [`BITS-1:0] reg2;
reg [`BITS-1:0] reg3;
reg [`BITS-1:0] reg4;
reg [`BITS-1:0] reg5;
reg [`BITS-1:0] reg6;

wire [`BITS-1:0] out_1;
wire [`BITS-1:0] out_2;
wire [`BITS-1:0] out_3;
wire [`BITS-1:0] out_4;

// ASSIGN STATEMENTS
//assign	add1 = reg1 + in4;
wire [7:0] add1_control;
fpu_add add1_add
( 
	.clk(clock), 
	.opa(reg6), 
	.opb(in4), 
	.out(add1), 
	.control(add1_control) 
);

//assign	x1 = x3 * in1;
wire [7:0] x1_control;
fpu_mul x1_mul
( 
	.clk(clock), 
	.opa(x3), 
	.opb(in1), 
	.out(x1), 
	.control(x1_control) 
);

//assign	add2 = add5 + add1;
wire [7:0] add2_control;
fpu_add add2_add
( 
	.clk(clock), 
	.opa(add5), 
	.opb(add1), 
	.out(add2), 
	.control(add2_control) 
);

//assign 	x2 = x1 * add2;
wire [7:0] x2_control;
fpu_mul x2_mul
( 
	.clk(clock), 
	.opa(x1), 
	.opb(add2), 
	.out(x2), 
	.control(x2_control) 
);

//assign	add3 = in1 + reg1;
wire [7:0] add3_control;
fpu_add add3_add
( 
	.clk(clock), 
	.opa(in1), 
	.opb(reg6), 
	.out(add3), 
	.control(add3_control) 
);

//assign	x3 = in3 * in1;
wire [7:0] x3_control;
fpu_mul x3_mul
( 
	.clk(clock), 
	.opa(in3), 
	.opb(in1), 
	.out(x3), 
	.control(x3_control) 
);


//assign	add4 = in5 + in3;
wire [7:0] add4_control;
fpu_add add4_add
( 
	.clk(clock), 
	.opa(in5), 
	.opb(in3), 
	.out(add4), 
	.control(add4_control) 
);

//assign	x4 = in5 * in4;
wire [7:0] x4_control;
fpu_mul x4_mul
( 
	.clk(clock), 
	.opa(in5), 
	.opb(in4), 
	.out(x4), 
	.control(x4_control) 
);

//assign	add5 = in5 + in4;
wire [7:0] add5_control;
fpu_add add5_add
( 
	.clk(clock), 
	.opa(in5), 
	.opb(in4), 
	.out(add5), 
	.control(add5_control) 
);

assign	out_1 = x2;
assign 	out_2 = add3;
assign	out_3 = add4;
assign	out_4 = x4;

always @(posedge clock)
begin
	reg1 <= in2;
	reg2 <= reg1;
	reg3 <= reg2;
	reg4 <= reg3;
	reg5 <= reg4;
	reg6 <= reg5;
end

endmodule
module 	mm3(clock, 
		reset,
		a1,
		a2,
		a3, 
		b1,
		b2,
		b3,
		out
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;

input [`BITS-1:0] a1;
input [`BITS-1:0] a2;
input [`BITS-1:0] a3;
input [`BITS-1:0] b1;
input [`BITS-1:0] b2;
input [`BITS-1:0] b3;

output [`BITS-1:0] out;


wire [`BITS-1:0] x1;
wire [`BITS-1:0] x2;
wire [`BITS-1:0] x3;
wire [`BITS-1:0] add4;
wire [`BITS-1:0] add5;

reg [`BITS-1:0] x3_reg1;
reg [`BITS-1:0] x3_reg2;
reg [`BITS-1:0] x3_reg3;
reg [`BITS-1:0] x3_reg4;
reg [`BITS-1:0] x3_reg5;
reg [`BITS-1:0] x3_reg6;


wire [`BITS-1:0] out;

// ASSIGN STATEMENTS
//assign	x1 = a1 * b1;
wire [7:0] x1_control;
fpu_mul x1_mul
( 
	.clk(clock), 
	.opa(a1), 
	.opb(b1), 
	.out(x1), 
	.control(x1_control) 
);

//assign	x2 = a2 * b2;
wire [7:0] x2_control;
fpu_mul x2_mul
( 
	.clk(clock), 
	.opa(a2), 
	.opb(b2), 
	.out(x2), 
	.control(x2_control) 
);

//assign	x3 = a3 * b3;
wire [7:0] x3_control;
fpu_mul x3_mul
( 
	.clk(clock), 
	.opa(a3), 
	.opb(b3), 
	.out(x3), 
	.control(x3_control) 
);

//assign	add4 = x1 + x2;
wire [7:0] add4_control;
fpu_add add4_add
( 
	.clk(clock), 
	.opa(x1), 
	.opb(x2), 
	.out(add4), 
	.control(add4_control) 
);

//assign	out = add4 + x3_reg5;
wire [7:0] out_control;
fpu_add out_add
( 
	.clk(clock), 
	.opa(add4), 
	.opb(x3_reg6), 
	.out(out), 
	.control(out_control) 
);
always @(posedge clock)
begin
	x3_reg1 <= x3;
	x3_reg2 <= x3_reg1;
	x3_reg3 <= x3_reg2;
	x3_reg4 <= x3_reg3;
	x3_reg5 <= x3_reg4;
	x3_reg6 <= x3_reg5;

end

endmodule
module 	dscg(clock, 
		reset,
		cos, 
		one, 
		s1,
		s2,
		s1_out,
		s2_out 
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;

input [`BITS-1:0] cos;
input [`BITS-1:0] one;
input [`BITS-1:0] s1;
input [`BITS-1:0] s2;

output [`BITS-1:0] s1_out;
output [`BITS-1:0] s2_out;


wire [`BITS-1:0]	add1;
wire [`BITS-1:0]	x2;
wire [`BITS-1:0]	x3;

wire [`BITS-1:0]	sub5;
wire [`BITS-1:0]	x6;
wire [`BITS-1:0]	x7;

wire [`BITS-1:0] s1_out;
wire [`BITS-1:0] s2_out;

reg [`BITS-1:0] x3_reg1;

reg [`BITS-1:0] x3_reg2;
reg [`BITS-1:0] x3_reg3;
reg [`BITS-1:0] x3_reg4;
reg [`BITS-1:0] x3_reg5;
reg [`BITS-1:0] x3_reg6;


reg [`BITS-1:0] x7_reg1;

reg [`BITS-1:0] x7_reg2;
reg [`BITS-1:0] x7_reg3;
reg [`BITS-1:0] x7_reg4;
reg [`BITS-1:0] x7_reg5;
reg [`BITS-1:0] x7_reg6;

//assign add1 	= cos + one;
wire [7:0] add1_control;
fpu_add add1_add
( 
	.clk(clock), 
	.opa(cos), 
	.opb(one), 
	.out(add1), 
	.control(add1_control) 
);

//assign x2 		= add1 * s2;
wire [7:0] x2_control;
fpu_mul x2_mul
( 
	.clk(clock), 
	.opa(add1), 
	.opb(s2), 
	.out(x2), 
	.control(x2_control) 
);

//assign x3		= cos * s1;
wire [7:0] x3_control;
fpu_mul x3_mul
( 
	.clk(clock), 
	.opa(cos), 
	.opb(s1), 
	.out(x3), 
	.control(x3_control) 
);

//assign s1_out 	= x2 + x3_reg1;
wire [7:0] s1_out_control;
fpu_add s1_out_add
( 
	.clk(clock), 
	.opa(x2), 
	.opb(x3_reg6), 
	.out(s1_out), 
	.control(s1_out_control) 
);

//assign	sub5 	= one - cos;
wire [7:0] sub5_control;
fpu_add sub5_add
( 
	.clk(clock), 
	.opa(one), 
	.opb(cos), 
	.out(sub5), 
	.control(sub5_control) 
);

//assign	x6 		= sub5 * s1;
wire [7:0] x6_control;
fpu_mul x6_mul
( 
	.clk(clock), 
	.opa(sub5), 
	.opb(s1), 
	.out(x6), 
	.control(x6_control) 
);


//assign 	x7 		= cos * s2;
wire [7:0] x7_control;
fpu_mul x7_mul
( 
	.clk(clock), 
	.opa(cos), 
	.opb(s2), 
	.out(x7), 
	.control(x7_control) 
);

//assign	s2_out 	= x6 + x7_reg1;
wire [7:0] s2_out_control;
fpu_add s2_out_add
( 
	.clk(clock), 
	.opa(x6), 
	.opb(x7_reg6), 
	.out(s2_out), 
	.control(s2_out_control) 
);

always @(posedge clock)
begin

	x3_reg1 <= x3;
	x3_reg2 <= x3_reg1;
	x3_reg3 <= x3_reg2;
	x3_reg4 <= x3_reg3;
	x3_reg5 <= x3_reg4;
	x3_reg6 <= x3_reg5;

	x7_reg1 <= x7;
	x7_reg2 <= x7_reg1;
	x7_reg3 <= x7_reg2;
	x7_reg4 <= x7_reg3;
	x7_reg5 <= x7_reg4;
	x7_reg6 <= x7_reg5;
end

endmodule
module 	ode(clock, 
		reset,
		select,
		h,
		half,
		y_pi_in, 
		t_pi_in,
		y_pi_out,
		t_pi_out 
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;
input select; 
input [`BITS-1:0] h;
input [`BITS-1:0] half;
input [`BITS-1:0] y_pi_in;
input [`BITS-1:0] t_pi_in;

output [`BITS-1:0] y_pi_out;
output [`BITS-1:0] t_pi_out;
output [7:0] x1_control;


wire [`BITS-1:0] x1;
wire [`BITS-1:0] sub2;
wire [`BITS-1:0] x3;
wire [`BITS-1:0] add4;
wire [`BITS-1:0] add5;

wire [`BITS-1:0] y_pi;
wire [`BITS-1:0] t_pi;

reg [`BITS-1:0] t_reg1;
reg [`BITS-1:0] t_reg2;
reg [`BITS-1:0] t_reg3;
reg [`BITS-1:0] t_reg4;
reg [`BITS-1:0] t_reg5;
reg [`BITS-1:0] t_reg6;
reg [`BITS-1:0] t_reg7;
reg [`BITS-1:0] t_reg8;
reg [`BITS-1:0] t_reg9;
reg [`BITS-1:0] t_reg10;
reg [`BITS-1:0] t_reg11;
reg [`BITS-1:0] t_reg12;

reg [`BITS-1:0] y_pi_reg1;
reg [`BITS-1:0] y_pi_reg2;
reg [`BITS-1:0] y_pi_reg3;
reg [`BITS-1:0] y_pi_reg4;
reg [`BITS-1:0] y_pi_reg5;
reg [`BITS-1:0] y_pi_reg6;
reg [`BITS-1:0] y_pi_reg7;
reg [`BITS-1:0] y_pi_reg8;
reg [`BITS-1:0] y_pi_reg9;
reg [`BITS-1:0] y_pi_reg10;
reg [`BITS-1:0] y_pi_reg11;
reg [`BITS-1:0] y_pi_reg12;
wire [`BITS-1:0] y_pi_out;
reg [`BITS-1:0] y_pi_out_reg;

wire [`BITS-1:0] t_pi_out;

// ASSIGN STATEMENTS
assign y_pi = select ? y_pi_in : add4;
assign t_pi = select ? t_pi_in : t_reg1;

//assign	x1 = h * half;
wire [7:0] x1_control;
fpu_mul x1_mul
( 
	.clk(clock), 
	.opa(h), 
	.opb(half), 
	.out(x1), 
	.control(x1_control) 
);

//assign	sub2 = t_pi - y_pi;
wire [7:0] sub2_control;
fpu_add sub2_add
( 
	.clk(clock), 
	.opa(t_pi), 
	.opb(y_pi), 
	.out(sub2), 
	.control(sub2_control) 
);

//assign	x3 = x1 * sub2;

wire [7:0] x3_control;
fpu_mul x3_mul
( 
	.clk(clock), 
	.opa(x1), 
	.opb(sub2), 
	.out(x3), 
	.control(x3_control) 
);

//assign	add4 = y_pi_reg1 + x3;
wire [7:0] add4_control;
fpu_add add4_add
( 
	.clk(clock), 
	.opa(y_pi_reg12), 
	.opb(x3), 
	.out(add4), 
	.control(add4_control) 
);

//assign	add5 = h + t_pi;
wire [7:0] add5_control;
fpu_add add5_add
( 
	.clk(clock), 
	.opa(h), 
	.opb(t_pi), 
	.out(add5), 
	.control(add5_control) 
);

//assign	y_pi_out = add4;
assign	y_pi_out = y_pi_out_reg;
assign	t_pi_out = t_reg12;

always @(posedge clock)
begin
	y_pi_out_reg <= add4;
	t_reg1 <= add5;
	t_reg2 <= t_reg1;
	t_reg3 <= t_reg2;
	t_reg4 <= t_reg3;
	t_reg5 <= t_reg4;
	t_reg6 <= t_reg5;
	t_reg7 <= t_reg6;
	t_reg8 <= t_reg7;
	t_reg9 <= t_reg8;
	t_reg10 <= t_reg9;
	t_reg11 <= t_reg10;
	t_reg12 <= t_reg11;

	y_pi_reg1 <= y_pi;
	y_pi_reg2 <= y_pi_reg1;
	y_pi_reg3 <= y_pi_reg2;	
	y_pi_reg4 <= y_pi_reg3;	
	y_pi_reg5 <= y_pi_reg4;	
	y_pi_reg6 <= y_pi_reg5;	
	y_pi_reg7 <= y_pi_reg6;	
	y_pi_reg8 <= y_pi_reg7;	
	y_pi_reg9 <= y_pi_reg8;	
	y_pi_reg10 <= y_pi_reg9;	
	y_pi_reg11 <= y_pi_reg10;	
	y_pi_reg12 <= y_pi_reg11;	

end
endmodule
module 	fir(clock, 
		reset,
		x,
		k0,
		k1, 
		k2,
		k3, 
		out 
);

// SIGNAL DECLARATIONS
input	clock;
input 	reset;

input [`BITS-1:0] x;
input [`BITS-1:0] k0;
input [`BITS-1:0] k1;
input [`BITS-1:0] k2;
input [`BITS-1:0] k3;

output [`BITS-1:0] out;

wire [`BITS-1:0] x0k0;
wire [`BITS-1:0] x1k1;
wire [`BITS-1:0] x2k2;
wire [`BITS-1:0] x3k3;

wire [`BITS-1:0] add0;
wire [`BITS-1:0] add1;
wire [`BITS-1:0] add2;
wire [`BITS-1:0] add3;

reg [`BITS-1:0] x_reg1;
reg [`BITS-1:0] x_reg2;
reg [`BITS-1:0] x_reg3;
reg [`BITS-1:0] x_reg4;
reg [`BITS-1:0] x_reg5;
reg [`BITS-1:0] x_reg6;
reg [`BITS-1:0] x_reg7;
reg [`BITS-1:0] x_reg8;
reg [`BITS-1:0] x_reg9;
reg [`BITS-1:0] x_reg10;
reg [`BITS-1:0] x_reg11;
reg [`BITS-1:0] x_reg12;
reg [`BITS-1:0] x_reg13;
reg [`BITS-1:0] x_reg14;
reg [`BITS-1:0] x_reg15;
reg [`BITS-1:0] x_reg16;
reg [`BITS-1:0] x_reg17;
reg [`BITS-1:0] x_reg18;

wire [`BITS-1:0] out;
wire [`BITS-1:0] out_temp;
reg [`BITS-1:0] out_reg;

assign out= out_reg;

// ASSIGN STATEMENTS

//assign	x0k0 = k0 * x;
wire [7:0] x0k0_control;
fpu_mul x0k0_mul
( 
	.clk(clock), 
	.opa(k0), 
	.opb(x), 
	.out(x0k0), 
	.control(x0k0_control) 
);

//assign	x1k1 = k1 * x_reg1;
wire [7:0] x1k1_control;
fpu_mul x1k1_mul
( 
	.clk(clock), 
	.opa(k1), 
	.opb(x_reg6), 
	.out(x1k1), 
	.control(x1k1_control) 
);

//assign	x2k2 = k2 * x_reg2;
wire [7:0] x2k2_control;
fpu_mul x2k2_mul
( 
	.clk(clock), 
	.opa(k2), 
	.opb(x_reg12), 
	.out(x2k2), 
	.control(x2k2_control) 
);

//assign	x3k3 = k3 * x_reg3;
wire [7:0] x3k3_control;
fpu_mul x3k3_mul
( 
	.clk(clock), 
	.opa(k3), 
	.opb(x_reg18), 
	.out(x3k3), 
	.control(x3k3_control) 
);

//assign	add0 = x0k0 + x1k1;
wire [7:0] add0_control;
fpu_add add0_add
( 
	.clk(clock), 
	.opa(x0k0), 
	.opb(x1k1), 
	.out(add0), 
	.control(add0_control) 
);

//assign	add1 = add0 + x2k2;
wire [7:0] add1_control;
fpu_add add1_add
( 
	.clk(clock), 
	.opa(add0), 
	.opb(x2k2), 
	.out(add1), 
	.control(add1_control) 
);

//assign	out = add1 + x3k3;
wire [7:0] out_temp_control;
fpu_add out_temp_add
( 
	.clk(clock), 
	.opa(add1), 
	.opb(x3k3), 
	.out(out_temp), 
	.control(out_temp_control) 
);

always @(posedge clock)
begin
	out_reg <= out_temp;
	x_reg1 <= x;
	x_reg2 <= x_reg1;
	x_reg3 <= x_reg2;
	x_reg4 <= x_reg3;
	x_reg5 <= x_reg4;
	x_reg6 <= x_reg5;
	x_reg7 <= x_reg6;
	x_reg8 <= x_reg7;
	x_reg9 <= x_reg8;
	x_reg10 <= x_reg9;
	x_reg11 <= x_reg10;
	x_reg12 <= x_reg11;
	x_reg13 <= x_reg12;
	x_reg14 <= x_reg13;
	x_reg15 <= x_reg14;
	x_reg16 <= x_reg15;
	x_reg17 <= x_reg16;
	x_reg18 <= x_reg17;

end

endmodule
module multi_consumer_tb();

    reg clock, rst;
    reg [15:0] d_in;
    wire [15:0] d_out_1, d_out_2, d_out_4, d_out_7;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
    
        d_in = 16'b0;

        #30
        d_in = 16'hffff;

        #20
        d_in = 16'h00ff;

        #20
        d_in = 16'h0000;

        #40
        $display($time, " << Simulation Complete >>");
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_in = %h, d_out_1 = %h, d_out_2 = %h d_out_4 = %h d_out_7 = %h",
                           clock, rst, d_in, d_out_1, d_out_2, d_out_4, d_out_7);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // multi_consumer DUT
    multi_consumer dut ( .d_in(d_in),
                         .d_out_1(d_out_1),
                         .d_out_2(d_out_2),
                         .d_out_4(d_out_4),
                         .d_out_7(d_out_7),
                         .clock(clock),
                         .rst(rst)
                        );

endmodule
module multi_consumer_tb();

    reg clock, rst;
    reg [15:0] d_in;
    wire [15:0] d_out_1, d_out_2, d_out_4, d_out_7;
    wire rdy;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
    
        d_in = 16'b0;

        wait ( rdy == 1'b1 );
        begin
            d_in = 16'hffff;
        end

        #30
        d_in = 16'h00ff;

        #20
        d_in = 16'h0000;

        #40
        $display($time, " << Simulation Complete >>");
        $finish;
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_in = %h, d_out_1 = %h, d_out_2 = %h d_out_4 = %h d_out_7 = %h",
                           clock, rst, d_in, d_out_1, d_out_2, d_out_4, d_out_7);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // multi_consumer DUT
    multi_consumer dut ( .d_in(d_in),
                         .d_out_1(d_out_1),
                         .d_out_2(d_out_2),
                         .d_out_4(d_out_4),
                         .d_out_7(d_out_7),
                         .clock(clock),
                         .rst(rst),
                         .rdy(rdy)
                        );

endmodule
module simple_comp_tb();

    reg clock, rst;
    reg [15:0] a_in, b_in, c_in;
    wire [15:0] d_out;
    wire rdy;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
       
        a_in = 16'h0;
        b_in = 16'h0;
        c_in = 16'b0;

        wait ( rdy == 1'b1 )
        begin
            a_in = 16'h0;
            b_in = 16'h0;
            c_in = 16'h0;
        end

        #30
        a_in = 16'hfff;
        b_in = 16'hfff;
        c_in = 16'hfff;

        #20
        a_in = 16'h0;
        b_in = 16'h0;

        #20
        a_in = 16'h666;
        b_in = 16'h666;
        c_in = 16'h666;

        #100
        $display($time, " << Simulation Complete >>");
        $finish;
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, a_in = %h, b_in = %h, c_in = %h, d_out = %h",
                           clock,      rst,      a_in, b_in, c_in, d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // simple_comp DUT
    simple_comp dut ( .a_in(a_in),
                      .b_in(b_in),
                      .c_in(c_in),
                      .d_out(d_out),
                      .clock(clock),
                      .rst(rst),
                      .rdy(rdy)
                    );

endmodule
module simple_comp_tb();

    reg clock, rst;
    reg [15:0] a_in, b_in, c_in;
    wire [15:0] d_out;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
       
        a_in = 16'h0;
        b_in = 16'h0;
        c_in = 16'b0;

        #30
        a_in = 16'hfff;
        b_in = 16'hfff;
        c_in = 16'hfff;

        #20
        a_in = 16'h0;
        b_in = 16'h0;

        #20
        a_in = 32'h666;
        b_in = 32'h666;
        c_in = 32'h666;

        #100
        $display($time, " << Simulation Complete >>");
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, a_in = %h, b_in = %h, c_in = %h, d_out = %h",
                           clock,      rst,      a_in, b_in, c_in, d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // simple_comp DUT
    simple_comp dut ( .a_in(a_in),
                      .b_in(b_in),
                      .c_in(c_in),
                      .d_out(d_out),
                      .clock(clock),
                      .rst(rst)
                    );

endmodule
module dcounter_tb();

    reg clock, rst;
    reg d_en;
    wire [15:0] d_out;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
        
        d_en = 1'b0;

        #50
        rst = 1'b0;
        d_en = 1'b1;

        #1311220
        $display($time, " << Simulation Complete >>");
        $stop;
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_en = %b, d_out = %h", 
                           clock,      rst,      d_en,      d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #40 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // dcounter DUT
    dcounter dut (   .d_out(d_out),
                     .d_en(d_en),
                     .clock(clock),
                     .rst(rst)
                   );

endmodule
module dcounter_tb();

    reg clock, rst;
    reg d_en;
    wire rdy;
    wire [15:0] d_out;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
        
        d_en = 1'b0;

        wait (rdy == 1'b1)
            begin
                 d_en = 1'b0;
            end

        #10
        d_en = 1'b1;

        #1311220
        $display($time, " << Simulation Complete >>");
        $finish;
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_en = %b, d_out = %h", 
                           clock,      rst,      d_en,      d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #40 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // dcounter DUT
    dcounter dut (   .d_out(d_out),
                     .d_en(d_en),
                     .clock(clock),
                     .rst(rst),
                     .rdy(rdy)
                   );

endmodule
module ff_en_tb();

    reg clock, rst;
    reg [9:0] d_in;
    reg d_en; 
    wire [9:0] d_out;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
        
        d_in = 10'b0;
        d_en = 1'b0;

        #30
        d_in = 10'h3ff;
        d_en = 1'b1;

        #20
        d_in = 10'h0;
        d_en = 1'b0;

        #20
        d_in = 10'h155;
        d_en = 1'b1;

        #20
        d_in = 10'h288;
        d_en = 1'b0;

        #20
        d_in = 10'h288;
        d_en = 1'b1;

        #20
        d_in = 10'h0;
        d_en = 1'b1;

        #40
        $display($time, " << Simulation Complete >>");
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_in = %h, d_en = %b, d_out = %h", 
                           clock,      rst,      d_in,      d_en,      d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // ff_en DUT
    ff_en dut ( .d_in(d_in),
                     .d_out(d_out),
                     .d_en(d_en),
                     .clock(clock),
                     .rst(rst)
                   );

endmodule
module ff_en_tb();

    reg clock, rst;
    reg [9:0] d_in;
    reg d_en; 
    wire [9:0] d_out;

    wire rdy;

    initial
    begin
        $display($time, " << Starting the Simulation >>");
        
        d_in = 10'b0;
        d_en = 1'b0;

        wait ( rdy == 1'b1 )
        #10
        begin
            d_in = 10'h3ff;
            d_en = 1'b1;
        end

        #20
        d_in = 10'h0;
        d_en = 1'b0;

        #20
        d_in = 10'h155;
        d_en = 1'b1;

        #20
        d_in = 10'h288;
        d_en = 1'b0;

        #20
        d_in = 10'h288;
        d_en = 1'b1;

        #20
        d_in = 10'h0;
        d_en = 1'b1;

        #40
        $display($time, " << Simulation Complete >>");
        $finish;
    end

    initial
    begin
        $monitor($time, ", clock = %b, rst = %b, d_in = %h, d_en = %b, d_out = %h", 
                           clock,      rst,      d_in,      d_en,      d_out);
    end

    initial
    begin
        clock = 1'b1;
        rst = 1'b1;
        #20 rst = 1'b0;
    end

    always
    begin
        #10 clock = ~clock;
    end

    // ff_en DUT
    ff_en dut ( .d_in(d_in),
                     .d_out(d_out),
                     .d_en(d_en),
                     .clock(clock),
                     .rst(rst),
                     .rdy(rdy)
                   );

endmodule