dakies/OSS_Verilog huggingface dataset:
module time_compare
  (
   input clk,
   input reset,
   input [63:0] time_now,
   input [63:0] trigger_time,
   output now,
   output early,
   output late,
   output too_early);

/*
   reg [63:0] time_diff;

   always @(posedge clk) begin
        if (reset) begin
            time_diff <= 64'b0;
            now <= 1'b0;
            late <= 1'b0;
            early <= 1'b0;
        end
        else begin
          time_diff <= trigger_time - time_now;
          now <= ~(|time_diff);
          late <= time_diff[63];
          early <= ~now & ~late;
       end
   end
   //assign now = ~(|time_diff);
   //assign late = time_diff[63];
   //assign early = ~now & ~late;
   assign too_early = 0; //not implemented
*/

    assign now = time_now == trigger_time;
    assign late = time_now > trigger_time;
    assign early = ~now & ~late;
    assign too_early = 0; //not implemented

endmodule // time_compare
module timekeeper
  #(parameter SR_TIME_HI = 0,
    parameter SR_TIME_LO = 1,
    parameter SR_TIME_CTRL = 2,
    parameter INCREMENT = 64'h1)
   (input clk, input reset, input pps, input sync_in, input strobe,
    input set_stb, input [7:0] set_addr, input [31:0] set_data,
    output reg [63:0] vita_time, output reg [63:0] vita_time_lastpps,
    output reg sync_out);

   //////////////////////////////////////////////////////////////////////////
   // timer settings for this module
   //////////////////////////////////////////////////////////////////////////
   wire [63:0] time_at_next_event;
   wire set_time_pps, set_time_now, set_time_sync;
   wire cmd_trigger;

   setting_reg #(.my_addr(SR_TIME_HI), .width(32)) sr_time_hi
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out(time_at_next_event[63:32]), .changed());

   setting_reg #(.my_addr(SR_TIME_LO), .width(32)) sr_time_lo
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out(time_at_next_event[31:0]), .changed());

   setting_reg #(.my_addr(SR_TIME_CTRL), .width(3)) sr_ctrl
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out({set_time_sync, set_time_pps, set_time_now}), .changed(cmd_trigger));

   //////////////////////////////////////////////////////////////////////////
   // PPS edge detection logic
   //////////////////////////////////////////////////////////////////////////
   reg pps_del, pps_del2;
   always @(posedge clk)
     {pps_del2,pps_del} <= {pps_del, pps};

   wire pps_edge = !pps_del2 & pps_del;

   //////////////////////////////////////////////////////////////////////////
   // arm the trigger to latch a new time when the ctrl register is written
   //////////////////////////////////////////////////////////////////////////
   reg armed;
   wire time_event = armed && ((set_time_now) || (set_time_pps && pps_edge) || (set_time_sync && sync_in));
   always @(posedge clk) begin
     if (reset) armed <= 1'b0;
     else if (cmd_trigger) armed <= 1'b1;
     else if (time_event) armed <= 1'b0;
   end

   //////////////////////////////////////////////////////////////////////////
   // vita time tracker - update every tick or when we get an "event"
   //////////////////////////////////////////////////////////////////////////
   always @(posedge clk) begin
     sync_out <= 1'b0;
     if(reset) begin
       vita_time <= 64'h0;
     end else begin
         if (time_event) begin
           sync_out <= 1'b1;
           vita_time <= time_at_next_event;
         end else if (strobe) begin
	   vita_time <= vita_time + INCREMENT;
         end
     end
   end

   //////////////////////////////////////////////////////////////////////////
   // track the time at last pps so host can detect the pps
   //////////////////////////////////////////////////////////////////////////
   always @(posedge clk)
     if(reset)
       vita_time_lastpps <= 64'h0;
     else if(pps_edge)
       if(time_event)
         vita_time_lastpps <= time_at_next_event;
       else
         vita_time_lastpps <= vita_time + INCREMENT;

endmodule // timekeeper
module vrlp_to_compressed_vita_tb();

   reg clk    = 0;
   reg reset  = 1;
   
   always #10 clk = ~clk;
   
   initial $dumpfile("vrlp_to_compressed_vita_tb.vcd");
   initial $dumpvars(0,vrlp_to_compressed_vita_tb);

   task send_packet;
      input [63:0] data_start;
      input [31:0] len;
      
      begin
	 // Send a packet
	 @(posedge clk);
	 {i_tlast, i_tdata} <= { 1'b0, data_start };
	 i_tvalid <= 1;
	 @(posedge clk);
	 i_tdata <= 64'hAAAA_BBBB_CCCC_0000;
	 
	 repeat(len-2)
	   begin
	      i_tvalid <= 1;
	      @(posedge clk);
	      i_tdata <= i_tdata + 1;
	   end
	 i_tlast <= 1;
	 i_tdata <= i_tdata + 1;
	 @(posedge clk);
	 i_tvalid <= 1'b0;
	 
	 @(posedge clk);
      end
   endtask // send_packet
   
   
   initial
     begin
	#1000 reset = 0;
	#200000;
	$finish;
     end
   
   wire [63:0]  o_tdata;
   reg [63:0] 	i_tdata;
   wire [2:0] 	o_tuser;
   reg [2:0] 	i_tuser;
   reg 		i_tlast;
   wire 	o_tlast;
   wire		o_tvalid, i_tready;
   reg 		i_tvalid, o_tready;
   reg 		i_terror;
   
   localparam RPT_COUNT = 16;
   
   initial
     begin
	i_tvalid <= 0;
	o_tready <= 0;
	
	while(reset)
	  @(posedge clk);
	@(posedge clk);

	//send_packet(64'hA0,3'd0, 16, 0);
	send_packet(64'hAABC_0008_DEAD_BEEF, 4);
	send_packet(64'h7DEF_0008_8765_4321, 4);
	send_packet(64'hAABC_0007_F00D_1234, 4);
	send_packet(64'h7DEF_0007_ABCD_4321, 4);
	o_tready <= 1;
	//send_packet(64'hC0,3'd0, 16, 1);
	//send_packet(64'hD0,3'd0, 16, 0);
	//send_packet(64'hE0,3'd0, 16, 0);
	//send_packet(64'hF0,3'd0, 16, 0);

	@(posedge clk);

     end // initial begin

   wire i_terror_int, i_tlast_int, i_tready_int, i_tvalid_int;
   wire [2:0] i_tuser_int;
   wire [63:0] i_tdata_int;
   wire o_tlast_int, o_tready_int, o_tvalid_int;
   wire [2:0] o_tuser_int;
   wire [63:0] o_tdata_int;
   wire [63:0] vrlp_tdata;
   wire        vrlp_tlast, vrlp_tvalid, vrlp_tready;
   
   axi_fifo #(.WIDTH(65), .SIZE(10)) fifo
     (.clk(clk), .reset(reset), .clear(1'b0),
      .i_tdata({i_tlast,i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
      .o_tdata({i_tlast_int,i_tdata_int}), .o_tvalid(i_tvalid_int), .o_tready(i_tready_int));

   compressed_vita_to_vrlp dut0
     (.clk(clk), .reset(reset), .clear(1'b0),
      .i_tdata(i_tdata_int), .i_tlast(i_tlast_int), .i_tvalid(i_tvalid_int), .i_tready(i_tready_int),
      .o_tdata(vrlp_tdata), .o_tlast(vrlp_tlast), .o_tvalid(vrlp_tvalid), .o_tready(vrlp_tready));

   vrlp_to_compressed_vita dut1
     (.clk(clk), .reset(reset), .clear(1'b0),
      .i_tdata(vrlp_tdata), .i_tlast(vrlp_tlast), .i_tvalid(vrlp_tvalid), .i_tready(vrlp_tready),
      .o_tdata(o_tdata_int), .o_tlast(o_tlast_int), .o_tvalid(o_tvalid_int), .o_tready(o_tready_int));

   axi_fifo #(.WIDTH(65), .SIZE(10)) fifo_out
     (.clk(clk), .reset(reset), .clear(1'b0),
      .i_tdata({o_tlast_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
      .o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready));

   always @(posedge clk)
     if(o_tvalid & o_tready)
       begin
	  $display("%x",o_tdata);
	  if(o_tlast)
	    $display("======EOF========");
       end
endmodule // vrlp_to_compressed_vita_tb
module vrlp_to_compressed_vita
  (input clk, input reset, input clear,
   input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
   output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   wire [63:0] 	 o_tdata_int;
   wire 	 o_tlast_int, o_tvalid_int, o_tready_int;

   reg [1:0] 	 v2cv_state;
   reg [11:0] 	 seqnum;
   reg 		 trim_line;
		 
   localparam V2CV_VRLP = 2'd0;
   localparam V2CV_VRTH = 2'd1;
   localparam V2CV_BODY = 2'd2;
   localparam V2CV_DUMP = 2'd3;

   wire 	 is_ec = i_tdata[63:60] == 4'h5;
   wire 	 has_trailer = i_tdata[58] & ~is_ec;
   wire 	 has_time = |i_tdata[53:52];
   wire 	 eob = i_tdata[56] & ~is_ec;
   wire [15:0] 	 len = i_tdata[47:32];
   wire [31:0] 	 sid = i_tdata[31:0];
   
   wire [63:0] 	 compressed_hdr = { is_ec, has_trailer, has_time, eob, seqnum, len, sid };
   wire 	 bad_vita = |i_tdata[55:54]  /* has secs */ | i_tdata[59] /* has class */ | ( {i_tdata[63],i_tdata[61:60]} != 3'b001 );
   reg [15:0] 	 len_reg;
   wire [16:0] vita_words32 = i_tdata[16:0]-17'd4;
   assign trim_now = 0;

   always @(posedge clk)
     if(reset | clear)
       begin
	  v2cv_state <= V2CV_VRLP;
	  seqnum <= 12'd0;
	  trim_line <= 1'b0;
	  len_reg <= 16'd0;
       end
     else
       case(v2cv_state)
	 V2CV_VRLP :
	   if(i_tvalid)
	     begin
		seqnum <= i_tdata[31:20];
		trim_line <= i_tdata[0];
		len_reg <= vita_words32[16:1];
		if(~i_tlast)
		  v2cv_state <= V2CV_VRTH;
	     end

	 V2CV_VRTH :
	   if(i_tvalid & o_tready_int)
	     begin
	     len_reg <= len_reg - 16'd1;
	     if(i_tlast)
	       v2cv_state <= V2CV_VRLP;
	     else if(bad_vita)
	       v2cv_state <= V2CV_DUMP;
	     else
	       v2cv_state <= V2CV_BODY;
	     end

	 V2CV_BODY :
	   if(i_tvalid & o_tready_int)
	     begin
		len_reg <= len_reg - 16'd1;
		if(i_tlast)
		  v2cv_state <= V2CV_VRLP;
		else if(len_reg == 16'd0)
		  v2cv_state <= V2CV_DUMP;
	     end
	 V2CV_DUMP :
	   if(i_tvalid)
	     if(i_tlast)
	       v2cv_state <= V2CV_VRLP;
       endcase // case (v2cv_state)

   assign o_tdata_int = (v2cv_state == V2CV_VRTH) ? compressed_hdr : i_tdata;
   assign o_tlast_int = i_tlast | (len_reg == 16'd0);
   assign o_tvalid_int = i_tvalid && (((v2cv_state == V2CV_VRTH) && !bad_vita) || (v2cv_state == V2CV_BODY));
   assign i_tready = o_tready_int | (v2cv_state == V2CV_VRLP) | (v2cv_state == V2CV_DUMP);

   axi_fifo_short #(.WIDTH(65)) short_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({o_tlast_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
      .o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
      .space(), .occupied());

endmodule // vrlp_to_compressed_vita
module compressed_vita_to_vrlp
  (input clk, input reset, input clear,
   input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
   output [63:0] o_tdata, output [15:0] o_tuser, output o_tlast, output o_tvalid, input o_tready
   );

   wire [19:0] 	 vrlp_size = 20'd3 + {4'b0000,i_tdata[47:32]};
   reg 		 odd_len;
   reg [2:0] 	 cv2v_state;

   reg [63:0] 	 o_tdata_int;
   wire 	 o_tlast_int, o_tvalid_int, o_tready_int;
   
   localparam CV2V_VRLP      = 3'd0; // VRLP header
   localparam CV2V_VRT_ECH   = 3'd1; // Extension context header
   localparam CV2V_VRT_IFH   = 3'd2; // IF Data header
   localparam CV2V_BODY      = 3'd3;
   localparam CV2V_VEND_ODD  = 3'd4;
   localparam CV2V_VEND_EVEN = 3'd4;
   
   always @(posedge clk)
     if(reset | clear)
       begin
	  cv2v_state <= CV2V_VRLP;
	  odd_len <= 1'b0;
       end
     else
       case(cv2v_state)
	 CV2V_VRLP :
	   if(i_tvalid & o_tready_int)
	     begin
		odd_len <= i_tdata[32];
		if(i_tdata[63])
		  cv2v_state <= CV2V_VRT_ECH;
		else
		  cv2v_state <= CV2V_VRT_IFH;
	     end

	 CV2V_VRT_ECH, CV2V_VRT_IFH :
	   if(i_tvalid & o_tready_int)
	     cv2v_state <= CV2V_BODY;

	 CV2V_BODY :
	   if(i_tlast & i_tvalid & o_tready_int)
	     if(odd_len)
	       cv2v_state <= CV2V_VRLP;
	     else
	       cv2v_state <= CV2V_VEND_EVEN;
	 
	 CV2V_VEND_EVEN :
	   if(o_tready_int)
	     cv2v_state <= CV2V_VRLP;
       endcase // case (cv2v_state)
   
   assign i_tready = o_tready_int & (cv2v_state != CV2V_VRLP) & (cv2v_state != CV2V_VEND_EVEN);
   assign o_tvalid_int = i_tvalid | (cv2v_state == CV2V_VEND_EVEN);

   always @*
     case(cv2v_state)
       CV2V_VRLP      : o_tdata_int <= { 32'h5652_4c50 /*VRLP*/, i_tdata[59:48] /*seqnum*/, vrlp_size[19:0] };
       CV2V_VRT_ECH   : o_tdata_int <= { 4'h5 /*type*/, 4'h0, 3'b00, i_tdata[61] /*time*/, i_tdata[51:48] /*seqnum*/, i_tdata[47:32] /*len*/, i_tdata[31:0] /*sid*/ };
       CV2V_VRT_IFH   : o_tdata_int <= { 4'h1 /*type*/, 1'b0, i_tdata[62] /*TRL*/, 1'b0, i_tdata[60] /*eob*/, 3'b00, i_tdata[61] /*time*/, i_tdata[51:48] /*seqnum*/, i_tdata[47:32] /*len*/, i_tdata[31:0] /*sid*/ };
       CV2V_BODY      : o_tdata_int <= (i_tlast & odd_len) ? { i_tdata[63:32], 32'h5645_4E44 /*VEND*/ } : i_tdata;
       CV2V_VEND_EVEN : o_tdata_int <= { 32'h5645_4E44 /*VEND*/, 32'h0};
       default : o_tdata_int <= i_tdata;
     endcase // case (cv2v_state)
   
   assign o_tlast_int = (cv2v_state == CV2V_VEND_EVEN) | ((cv2v_state == CV2V_BODY) & i_tlast & odd_len);

   // Short FIFO before output
   axi_fifo_short #(.WIDTH(81)) axi_fifo_short
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({o_tlast_int, i_tdata[15:0], o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
      .o_tdata({o_tlast, o_tuser, o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
      .space(), .occupied());
   
endmodule // compressed_vita_to_vrlp
module quarter_rate_downconverter #(
  parameter WIDTH=24
)(
  input clk,
  input reset,
  input phase_sync,

  input [2*WIDTH-1:0] i_tdata,
  input i_tlast,
  input i_tvalid,
  output i_tready,

  output [2*WIDTH-1:0] o_tdata,
  output o_tlast,
  output o_tvalid,
  input o_tready,

  input dirctn
);

  // temporary signals for i and q after rotation
  reg [WIDTH-1:0] tmp_i = {WIDTH{1'b0}};
  reg [WIDTH-1:0] tmp_q = {WIDTH{1'b0}};

  // State machine types and reg
  localparam S0=0, S1=1, S2=2, S3=3;
  reg[1:0] cur_state;

  // split input into i and q signal
  wire[WIDTH-1:0] i_in, q_in;
  assign i_in = i_tdata[2*WIDTH-1:WIDTH];
  assign q_in = i_tdata[WIDTH-1:0];

  // The state machine doing the rotations among states
  always @(posedge clk) begin
    if(reset || phase_sync) begin
       cur_state <= S0;
    end else begin
      case (cur_state)
        S0: begin
            if(i_tvalid == 1'b1 && i_tready == 1'b1)
              if(dirctn == 1'b0)
                cur_state <= S1;
              else
                cur_state <= S3;
            else
              cur_state <= S0;
          end
        S1: begin
            if(i_tvalid == 1'b1 && i_tready == 1'b1)
              if(dirctn == 1'b0)
                cur_state <= S2;
              else
                cur_state <= S0;
            else
              cur_state <= S1;
          end
        S2: begin
            if(i_tvalid == 1'b1 && i_tready == 1'b1)
              if(dirctn == 1'b0)
                cur_state <= S3;
              else
                cur_state <= S1;
            else
              cur_state <= S2;
          end
        S3: begin
            if(i_tvalid == 1'b1 && i_tready == 1'b1)
              if(dirctn == 1'b0)
                cur_state <= S0;
              else
                cur_state <= S2;
            else
              cur_state <= S3;
          end
      endcase
    end
  end

  // Multiplication of input IQ signal with (1,i,-1,-i):
  always @(*) begin
    case (cur_state)
      S0: begin
          // S(t) * 1 = I(t) + iQ(t):
          tmp_i = i_in;
          tmp_q = q_in;
        end
      S1: begin
          // S(t) * i = -Q(t) + iI(t):
          tmp_i = -q_in;
          tmp_q = i_in;
        end
      S2: begin
          // S(t) * -1 = -I(t) - iQ(t):
          tmp_i = -i_in;
          tmp_q = -q_in;
        end
      S3: begin
          // S(t) * -i = Q(t) - iI(t):
          tmp_i = q_in;
          tmp_q = -i_in;
        end
      default: begin
          tmp_i = i_in;
          tmp_q = q_in;
        end
    endcase
  end

  // Flop for valid and ready signals and shortening of comb. paths.
  axi_fifo #(.WIDTH(2*WIDTH + 1), .SIZE(1)) flop (
    .clk(clk), .reset(reset), .clear(1'b0),
    .i_tdata({i_tlast, tmp_i, tmp_q}), .i_tvalid(i_tvalid), .i_tready(i_tready),
    .o_tdata({o_tlast, o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
    .occupied(), .space());

endmodule // quarter_rate_downconverter
module null_source
  #(parameter SR_LINES_PER_PACKET    = 129,
    parameter SR_LINE_RATE           = 130,
    parameter SR_ENABLE_STREAM       = 131)
   (input clk, input reset, input clear,
    input [31:0] sid,
    input set_stb, input [7:0] set_addr, input [31:0] set_data,
    output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   reg [11:0]      seqnum;
   wire [15:0]      rate;
   reg [1:0]      state;
   reg [15:0]      line_number;
   
   wire [63:0]      int_tdata;
   wire      int_tlast, int_tvalid, int_tready;

   wire [15:0]      len;
   reg [15:0]      count;
   reg [15:0]      packet_count;
   wire      enable;
   
   setting_reg #(.my_addr(SR_LINES_PER_PACKET), .width(16)) len_reg
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out(len), .changed());

   setting_reg #(.my_addr(SR_LINE_RATE), .width(16)) rate_reg
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out(rate), .changed());

   setting_reg #(.my_addr(SR_ENABLE_STREAM), .width(1)) enable_reg
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data),
      .out(enable), .changed());

   localparam IDLE = 2'd0;
   localparam HEAD = 2'd1;
   localparam DATA = 2'd2;

   always @(posedge clk)
      if(reset | clear) begin
         state <= IDLE;
         count <= 0;
         seqnum <= 0;
      end else begin
         case(state)
         IDLE :
            if(enable)
               state <= HEAD;
         HEAD :
            if(int_tvalid & int_tready) begin
               count <= 1;
               state <= DATA;
               seqnum <= seqnum + 1;
            end
         DATA :
            if(int_tvalid & int_tready)
               if(count >= len) begin
                  state <= IDLE;
                  count <= 0;
               end
            else
               count <= count + 1;
         default :
            state <= IDLE;
         endcase // case (state)
      end // else: !if(reset)

   wire [15:0] pkt_len = { len[12:0], 3'b000 } + 16'd8;
   
   assign int_tdata = (state == HEAD) ? { 4'b0000, seqnum, pkt_len, sid } : {~count,count,count,count} ;
   assign int_tlast = (count >= len);

   reg [15:0]  line_timer;
   always @(posedge clk)
      if(reset | clear)
         line_timer <= 0;
      else
         if(line_timer == 0)
            line_timer <= rate;
         else
            line_timer <= line_timer - 1;

   assign int_tvalid = ((state==HEAD)|(state==DATA)) & (line_timer==0);

   axi_packet_gate #(.WIDTH(64), .SIZE(10)) gate
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata(int_tdata), .i_tlast(int_tlast), .i_terror(1'b0), .i_tvalid(int_tvalid), .i_tready(int_tready),
      .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
   
endmodule // null_source
module delay_type4
  #(parameter MAX_LEN_LOG2=4,
    parameter WIDTH=16,
    parameter DELAY_VAL=0)
  (input clk, input reset, input clear,
    input [MAX_LEN_LOG2-1:0] len,
    input [WIDTH-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

  reg [MAX_LEN_LOG2-1:0] delay_count;

  wire delay_done = delay_count >= len;

  always @(posedge clk)
    if(reset | clear)
      delay_count <= 0;
    else
      if(~delay_done & i_tvalid & o_tready)
        delay_count <= delay_count + 1;

  assign o_tdata = delay_done ? i_tdata : DELAY_VAL;
  assign o_tlast = delay_done ? i_tlast : 1'b0;      // FIXME (carried over from delay_type2) think about this more, no answer is perfect in all situations
  assign o_tvalid = delay_done ? i_tvalid : 1'b0;
  assign i_tready = delay_done ? o_tready : 1'b0;

endmodule // delay_type4
module cvita_hdr_parser #(
  parameter REGISTER = 1    // 0 = No registering, header / vita_time only valid when hdr_stb / vita_time_stb is asserted (lower resource utilization)
                            // 1 = Header / vita time are registered and valid for the length of entire packet.
)(
  input clk, input reset, input clear,
  output hdr_stb,
  output [1:0] pkt_type, output eob, output has_time,
  output [11:0] seqnum, output [15:0] length, output [15:0] payload_length,
  output [15:0] src_sid, output [15:0] dst_sid,
  output vita_time_stb,
  output [63:0] vita_time,
  input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
  output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
);

  generate
    if (REGISTER) begin
      axi_fifo_flop2 #(.WIDTH(65)) axi_fifo_flop (
        .clk(clk), .reset(reset), .clear(clear),
        .i_tdata({i_tlast,i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
        .o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
        .space(), .occupied());
    end else begin
      assign o_tdata  = i_tdata;
      assign o_tlast  = i_tlast;
      assign o_tvalid = i_tvalid;
      assign i_tready = o_tready;
    end
  endgenerate

  reg first_time, first_line, read_time;
  wire [63:0] hdr, hdr_vita_time;
  reg [63:0] hdr_reg, vita_time_reg;

  always @(posedge clk) begin
    if (reset | clear) begin
      first_time    <= 1'b1;
      first_line    <= 1'b1;
      read_time     <= 1'b0;
      hdr_reg       <= 64'd0;
      vita_time_reg <= 64'd0;
    end else begin
      if (o_tvalid & o_tready) begin
        first_time      <= 1'b0;
        if (first_line) begin
          hdr_reg       <= o_tdata;
          first_line    <= 1'b0;
          if (has_time & ~o_tlast) begin
            read_time   <= 1'b1;
          end
        end
        if (read_time) begin
          vita_time_reg <= o_tdata;
          read_time     <= 1'b0;
        end
        if (o_tlast) begin
          first_line    <= 1'b1;
        end
      end
    end
  end

  // REGISTER = 0: Always use o_tdata, output only valid when hdr_stb = 1
  // REGISTER = 1: Mux to make sure header output is available immediately and also registered for rest of packet.
  assign hdr            = (hdr_stb       | (REGISTER == 0)) ? o_tdata : hdr_reg;
  assign hdr_vita_time  = (vita_time_stb | (REGISTER == 0)) ? o_tdata : vita_time_reg;

  assign hdr_stb        = first_line & o_tvalid & o_tready;
  assign pkt_type       = hdr[63:62];
  assign has_time       = hdr[61];
  assign eob            = hdr[60];
  assign seqnum         = hdr[59:48];
  assign length         = hdr[47:32];
  assign payload_length = length - (has_time ? 16'd16 : 16'd8);
  assign src_sid        = hdr[31:16];
  assign dst_sid        = hdr[15:0];

  assign vita_time_stb  = read_time & o_tvalid & o_tready;
  assign vita_time      = hdr_vita_time;

endmodule
module noc_block_fosphor_chdr
(
  input clk, input rst,
  input  [127:0] i_tuser, input i_tlast, input i_tvalid, input i_tready,
  output [127:0] o_chdr,  input o_tlast, input o_tvalid, input o_tready
);

  reg chdr_cap_next, chdr_pending, chdr_cur_valid;
  wire chdr_cap_cur;
  reg [127:0] chdr_next;
  reg [127:0] chdr_cur;

  always @(posedge clk)
  begin
    // When to capture Next
    if (rst)
      chdr_cap_next <= 1'b1;
    else if (i_tvalid & i_tready)
      chdr_cap_next <= i_tlast;

    // Next CHDR
    if (chdr_cap_next)
      chdr_next <= i_tuser;

    // When to capture
    if (chdr_cap_next)
      chdr_pending <= 1'b1;
    else if (chdr_cap_cur)
      chdr_pending <= 1'b0;

    // Current CHDR
    if (chdr_cap_cur)
      chdr_cur <= chdr_next;

    if (rst)
      chdr_cur_valid <= 1'b0;
    else if (chdr_cap_cur)
      chdr_cur_valid <= chdr_pending;
  end

  assign chdr_cap_cur = chdr_pending & ((o_tlast & o_tvalid & o_tready) | ~chdr_cur_valid);
  assign o_chdr = chdr_cur;

endmodule // noc_block_fosphor_chdr
module axi_clip
  #(parameter WIDTH_IN=24,
    parameter WIDTH_OUT=16,
    parameter FIFOSIZE=0)  // leave at 0 for a normal single flop
   (input clk, input reset,
    input [WIDTH_IN-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH_OUT-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   generate
     if (WIDTH_IN == WIDTH_OUT) begin
      assign o_tdata  = i_tdata;
      assign o_tlast  = i_tlast;
      assign o_tvalid = i_tvalid;
      assign i_tready = o_tready;
     end else begin
       wire overflow = |i_tdata[WIDTH_IN-1:WIDTH_OUT-1] & ~(&i_tdata[WIDTH_IN-1:WIDTH_OUT-1]);
       wire [WIDTH_OUT-1:0] out = overflow ?
         (i_tdata[WIDTH_IN-1] ? {1'b1,{(WIDTH_OUT-1){1'b0}}} : {1'b0,{(WIDTH_OUT-1){1'b1}}}) :
          i_tdata[WIDTH_OUT-1:0];

       axi_fifo #(.WIDTH(WIDTH_OUT+1), .SIZE(FIFOSIZE)) flop
         (.clk(clk), .reset(reset), .clear(1'b0),
          .i_tdata({i_tlast, out}), .i_tvalid(i_tvalid), .i_tready(i_tready),
          .o_tdata({o_tlast, o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
          .occupied(), .space());
     end
   endgenerate

endmodule // axi_clip
module noc_input_port #(
  parameter SR_FLOW_CTRL_BYTES_PER_ACK = 1,
  parameter SR_ERROR_POLICY = 2,
  parameter STR_SINK_FIFOSIZE = 11,
  parameter USE_TIME = 0
)(
  input clk, input reset, input clear,  // Note: Clear is used to clear the FIFO and flow control
  input [31:0] resp_sid,                // Stream ID used with response packets
  input set_stb, input [7:0] set_addr, input [31:0] set_data,
  // To / From NoC Shell
  input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
  output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready,
  // Flow control and error packets
  output [63:0] fc_tdata, output fc_tlast, output fc_tvalid, input fc_tready
);

  // Receive window / buffer
  wire [63:0] int_tdata;
  wire int_tlast, int_tvalid, int_tready;
  chdr_fifo_large #(.SIZE(STR_SINK_FIFOSIZE)) axi_fifo_receive_window (
    .clk(clk), .reset(reset), .clear(clear),
    .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
    .o_tdata(int_tdata), .o_tlast(int_tlast), .o_tvalid(int_tvalid), .o_tready(int_tready));

  // Flow control and error packet handling
  wire [63:0] fc_int_tdata, resp_int_tdata;
  wire fc_int_tlast, fc_int_tvalid, fc_int_tready, resp_int_tlast, resp_int_tvalid, resp_int_tready;
  noc_responder #(
    .SR_FLOW_CTRL_BYTES_PER_ACK(SR_FLOW_CTRL_BYTES_PER_ACK),
    .SR_ERROR_POLICY(SR_ERROR_POLICY),
    .USE_TIME(USE_TIME))
  noc_responder (
    .clk(clk), .reset(reset), .clear(clear),
    .resp_sid(resp_sid),
    .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
    .i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
    .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
    .fc_tdata(fc_int_tdata), .fc_tlast(fc_int_tlast), .fc_tvalid(fc_int_tvalid), .fc_tready(fc_int_tready),
    .resp_tdata(resp_int_tdata), .resp_tlast(resp_int_tlast), .resp_tvalid(resp_int_tvalid), .resp_tready(resp_int_tready));

  axi_mux #(.PRIO(0), .WIDTH(64), .PRE_FIFO_SIZE(0), .POST_FIFO_SIZE(1), .SIZE(2)) axi_mux (
    .clk(clk), .reset(reset), .clear(clear),
    .i_tdata({fc_int_tdata, resp_int_tdata}), .i_tlast({fc_int_tlast, resp_int_tlast}),
    .i_tvalid({fc_int_tvalid, resp_int_tvalid}), .i_tready({fc_int_tready, resp_int_tready}),
    .o_tdata(fc_tdata), .o_tlast(fc_tlast), .o_tvalid(fc_tvalid), .o_tready(fc_tready));

endmodule
module axi_clip_complex #(
  parameter WIDTH_IN  = 24,
  parameter WIDTH_OUT = 16,
  parameter FIFOSIZE  = 0)  // leave at 0 for a single flop
(
  input clk, input reset,
  input [2*WIDTH_IN-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
  output [2*WIDTH_OUT-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
);

  wire [WIDTH_IN-1:0]  ii_tdata, iq_tdata;
  wire                 ii_tlast, ii_tvalid, ii_tready, iq_tlast, iq_tvalid, iq_tready;

  wire [WIDTH_OUT-1:0] oi_tdata, oq_tdata;
  wire                 oi_tlast, oi_tvalid, oi_tready, oq_tlast, oq_tvalid, oq_tready;

  split_complex #(.WIDTH(WIDTH_IN)) split_complex (
    .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
    .oi_tdata(ii_tdata), .oi_tlast(ii_tlast), .oi_tvalid(ii_tvalid), .oi_tready(ii_tready),
    .oq_tdata(iq_tdata), .oq_tlast(iq_tlast), .oq_tvalid(iq_tvalid), .oq_tready(iq_tready));

  axi_clip #(.WIDTH_IN(WIDTH_IN), .WIDTH_OUT(WIDTH_OUT), .FIFOSIZE(FIFOSIZE)) axi_clip_i (
    .clk(clk), .reset(reset),
    .i_tdata(ii_tdata), .i_tlast(ii_tlast), .i_tvalid(ii_tvalid), .i_tready(ii_tready),
    .o_tdata(oi_tdata), .o_tlast(oi_tlast), .o_tvalid(oi_tvalid), .o_tready(oi_tready));

  axi_clip #(.WIDTH_IN(WIDTH_IN), .WIDTH_OUT(WIDTH_OUT), .FIFOSIZE(FIFOSIZE)) axi_clip_q (
    .clk(clk), .reset(reset),
    .i_tdata(iq_tdata), .i_tlast(iq_tlast), .i_tvalid(iq_tvalid), .i_tready(iq_tready),
    .o_tdata(oq_tdata), .o_tlast(oq_tlast), .o_tvalid(oq_tvalid), .o_tready(oq_tready));

  join_complex #(.WIDTH(WIDTH_OUT)) join_complex (
    .ii_tdata(oi_tdata), .ii_tlast(oi_tlast), .ii_tvalid(oi_tvalid), .ii_tready(oi_tready),
    .iq_tdata(oq_tdata), .iq_tlast(oq_tlast), .iq_tvalid(oq_tvalid), .iq_tready(oq_tready),
    .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));

endmodule
module axi_deserializer #(
  parameter WIDTH = 32)
(
  input clk, input rst, input reverse_output,
  input i_tdata, input  i_tlast, input i_tvalid,  output i_tready,
  output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
);

  reg flop_tlast, flop_tlast_latch;
  reg  [WIDTH-1:0] flop_tdata;
  wire [WIDTH-1:0] flop_tdata_reverse, flop_tdata_int;
  reg flop_tvalid;
  reg [$clog2(WIDTH)-1:0] i;

  always @(posedge clk) begin
    if (rst) begin
      flop_tdata       <= 'd0;
      flop_tvalid      <= 1'b0;
      flop_tlast       <= 1'b0;
      flop_tlast_latch <= 1'b0;
      i                <= WIDTH-1;
    end else begin
      flop_tvalid      <= 1'b0;
      if (i_tvalid & i_tready) begin
        flop_tdata[i]  <= i_tdata;
        if (i_tlast) begin
          flop_tlast_latch <= 1'b1;
        end
        if (i == 0) begin
          flop_tvalid      <= 1'b1;
          flop_tlast       <= flop_tlast_latch;
          flop_tlast_latch <= 1'b0;
          i                <= WIDTH-1;
        end else begin
          i                <= i - 1;
        end
      end
    end
  end

  // Reverse flop_tdata
  genvar k;
  generate
    for (k = 0; k < WIDTH; k = k + 1) assign flop_tdata_reverse[WIDTH-1-k] = flop_tdata;
  endgenerate

  assign flop_tdata_int = reverse_output ? flop_tdata_reverse : flop_tdata;

  axi_fifo_flop2 #(.WIDTH(WIDTH)) axi_fifo_flop (
    .clk(clk), .reset(rst), .clear(1'b0),
    .i_tdata({flop_tlast,flop_tdata_int}), .i_tvalid(flop_tvalid), .i_tready(i_tready),
    .o_tdata({o_tlast,o_tdata}),       .o_tvalid(o_tvalid),    .o_tready(o_tready),
    .space(), .occupied());

endmodule
module ram_to_fifo
  #(parameter DWIDTH=32,
    parameter AWIDTH=10)
   (input clk, input reset, input clear,
    // FIXME add writing port
    input [DWIDTH-1:0] config_tdata, input config_tlast, input config_tvalid, output config_tready,
    input [AWIDTH-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [DWIDTH-1:0] o_tdata, output reg o_tlast, output reg o_tvalid, input o_tready);

   // Write side
   reg [AWIDTH-1:0] 	write_addr;
   
   assign config_tready = 1'b1;

   always @(posedge clk)
     if(reset | clear)
       write_addr <= 0;
     else
       if(config_tvalid & config_tready)
	 if(config_tlast)
	   write_addr <= 0;
	 else
	   write_addr <= write_addr + 1;
      
   ram_2port #(.DWIDTH(DWIDTH), .AWIDTH(AWIDTH)) ram_2port
     (.clka(clk), .ena(1'b1), .wea(config_tvalid), .addra(write_addr), .dia(config_tdata), .doa(), // Write port
      .clkb(clk), .enb(i_tready & i_tvalid), .web(1'b0), .addrb(i_tdata), .dib({DWIDTH{1'b1}}), .dob(o_tdata)); // Read port

   // Read side
   assign i_tready = ~o_tvalid | o_tready;

   always @(posedge clk)
     if(reset | clear)
       begin
	  o_tvalid <= 1'b0;
	  o_tlast <= 1'b0;
       end
     else
       begin
	  o_tvalid <= (i_tready & i_tvalid) | (o_tvalid & ~o_tready);
	  if(i_tready & i_tvalid)
	    o_tlast <= i_tlast;
       end
   
endmodule // ram_to_fifo
module window
  #(parameter SR_WINDOW_SIZE = 0,
    parameter MAX_LOG2_OF_WINDOW_SIZE = 10,
    parameter COEFF_WIDTH = 16)
   (input clk, input reset, input clear,
    input set_stb, input [7:0] set_addr, input [31:0] set_data,
    input [COEFF_WIDTH-1:0] m_axis_coeff_tdata, input m_axis_coeff_tlast, input m_axis_coeff_tvalid, output m_axis_coeff_tready,
    input [31:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [31:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   wire [31:0]  n0_tdata, n1_tdata, n3_tdata, n4_tdata, n5_tdata, n6_tdata, n7_tdata, n8_tdata, n9_tdata;
   wire         n0_tlast, n1_tlast, n2_tlast, n3_tlast, n4_tlast, n5_tlast, n6_tlast, n7_tlast, n8_tlast, n9_tlast;
   wire         n0_tvalid, n1_tvalid, n2_tvalid, n3_tvalid, n4_tvalid, n5_tvalid, n6_tvalid, n7_tvalid, n8_tvalid, n9_tvalid;
   wire         n0_tready, n1_tready, n2_tready, n3_tready, n4_tready, n5_tready, n6_tready, n7_tready, n8_tready, n9_tready;

   wire [MAX_LOG2_OF_WINDOW_SIZE-1:0] n2_tdata;
   wire [MAX_LOG2_OF_WINDOW_SIZE:0] max;

   setting_reg #(.my_addr(SR_WINDOW_SIZE), .width(MAX_LOG2_OF_WINDOW_SIZE+1)) reg_max
     (.clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), .out(max));

   split_stream_fifo #(.WIDTH(32), .ACTIVE_MASK(4'b0011)) split_head
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
      .o0_tdata(n0_tdata), .o0_tlast(n0_tlast), .o0_tvalid(n0_tvalid), .o0_tready(n0_tready),
      .o1_tdata(n1_tdata), .o1_tlast(n1_tlast), .o1_tvalid(n1_tvalid), .o1_tready(n1_tready),
      .o2_tready(1'b0), .o3_tready(1'b0));

   counter #(.WIDTH(MAX_LOG2_OF_WINDOW_SIZE)) addr_gen
     (.clk(clk), .reset(reset), .clear(clear),
      .max(max),
      .i_tlast(1'b0), .i_tvalid(n1_tvalid), .i_tready(n1_tready),
      .o_tdata(n2_tdata), .o_tlast(n2_tlast), .o_tvalid(n2_tvalid), .o_tready(n2_tready));

   ram_to_fifo #(.DWIDTH(COEFF_WIDTH), .AWIDTH(MAX_LOG2_OF_WINDOW_SIZE)) window_coeffs
     (.clk(clk), .reset(reset), .clear(clear),
      .config_tdata(m_axis_coeff_tdata), .config_tlast(m_axis_coeff_tlast), .config_tvalid(m_axis_coeff_tvalid), .config_tready(m_axis_coeff_tready),
      .i_tdata(n2_tdata), .i_tlast(n2_tlast), .i_tvalid(n2_tvalid), .i_tready(n2_tready),
      .o_tdata(n3_tdata), .o_tlast(n3_tlast), .o_tvalid(n3_tvalid), .o_tready(n3_tready));

   mult_rc #(.WIDTH_REAL(COEFF_WIDTH), .WIDTH_CPLX(16), .WIDTH_P(16), .DROP_TOP_P(6))
   inst_mult_rc (
     .clk(clk), .reset(reset),
     .real_tdata(n3_tdata), .real_tlast(n3_tlast), .real_tvalid(n3_tvalid), .real_tready(n3_tready),
     .cplx_tdata(n0_tdata), .cplx_tlast(n0_tlast), .cplx_tvalid(n0_tvalid), .cplx_tready(n0_tready),
     .p_tdata(o_tdata), .p_tlast(o_tlast), .p_tvalid(o_tvalid), .p_tready(o_tready));

endmodule // window
module delay_type2
  #(parameter MAX_LEN_LOG2=10,
    parameter WIDTH=16,
    parameter DELAY_VAL=0)
   (input clk, input reset, input clear,
    input [MAX_LEN_LOG2-1:0] len,
    input [WIDTH-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   reg [MAX_LEN_LOG2-1:0] delay_count;

   wire 		  delay_done = delay_count >= len;
   
   always @(posedge clk)
     if(reset)
       delay_count <= 0;
     else
       if(~delay_done & o_tvalid & o_tready)
	 delay_count <= delay_count + 1;

   assign o_tdata = delay_done ? i_tdata : DELAY_VAL;
   assign o_tlast = delay_done ? i_tlast : 1'b0;      // FIXME think about this more, no answer is perfect in all situations
   assign o_tvalid = delay_done ? i_tvalid : 1'b1;
   assign i_tready = delay_done ? o_tready : 1'b0;
   
endmodule // delay_type2
module noc_responder #(
  parameter SR_FLOW_CTRL_BYTES_PER_ACK = 1,
  parameter SR_ERROR_POLICY = 2,
  parameter USE_TIME = 0
)(
  input clk, input reset, input clear,
  input [31:0] resp_sid,          // Stream ID used with response packets
  input set_stb, input [7:0] set_addr, input [31:0] set_data,
  input [63:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
  output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready,
  output [63:0] fc_tdata, output fc_tlast, output fc_tvalid, input fc_tready,
  output [63:0] resp_tdata, output resp_tlast, output resp_tvalid, input resp_tready
);

  /********************************************************
  ** WARNING: Order is important here! We must reply
  **          with flow control packets first before
  **          potentially dropping the packets due to
  **          an error.
  ********************************************************/
  wire [63:0] int_tdata;
  wire int_tlast, int_tvalid, int_tready;
  wire seqnum_error;
  flow_control_responder #(
    .SR_FLOW_CTRL_BYTES_PER_ACK(SR_FLOW_CTRL_BYTES_PER_ACK),
    .USE_TIME(USE_TIME))
  flow_control_responder (
    .clk(clk), .reset(reset), .clear(clear),
    .force_fc_pkt(seqnum_error),
    .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
    .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
    .o_tdata(int_tdata), .o_tlast(int_tlast), .o_tvalid(int_tvalid), .o_tready(int_tready),
    .fc_tdata(fc_tdata), .fc_tlast(fc_tlast), .fc_tvalid(fc_tvalid), .fc_tready(fc_tready));

  packet_error_responder #(
    .SR_ERROR_POLICY(SR_ERROR_POLICY),
    .USE_TIME(USE_TIME))
  packet_error_responder (
    .clk(clk), .reset(reset), .clear(clear),
    .sid(resp_sid),
    .seqnum_error(seqnum_error),
    .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
    .i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
    .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
    .resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready));

endmodule
module join_complex
  #(parameter WIDTH=16)
   (input [WIDTH-1:0] ii_tdata, input ii_tlast, input ii_tvalid, output ii_tready,
    input [WIDTH-1:0] iq_tdata, input iq_tlast, input iq_tvalid, output iq_tready,
    output [WIDTH*2-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready,
    output error);

   assign o_tdata = {ii_tdata,iq_tdata};

   assign o_tlast = ii_tlast;

   assign o_tvalid = ii_tvalid;

   assign ii_tready = o_tready;
   assign iq_tready = o_tready;

   assign  error = (ii_tlast ^ iq_tlast) | (ii_tvalid ^ iq_tvalid);
      
endmodule // join_complex
module noc_output_port #(
  parameter SR_FLOW_CTRL_EN = 0,
  parameter SR_FLOW_CTRL_WINDOW_SIZE = 1,
  parameter SR_FLOW_CTRL_PKT_LIMIT = 2,
  parameter PORT_NUM=0,
  parameter MTU=10,      // includes some extra space due to cascade fifo
  parameter USE_GATE=0   // Gate only necessary if partial packets can get to us.  axi_wrapper and chdr_framer don't need gates.
)(
  input clk, input reset, input clear,
  // Settings bus
  input set_stb, input [7:0] set_addr, input [31:0] set_data,
  // To NoC Shell
  output [63:0] dataout_tdata, output dataout_tlast, output dataout_tvalid, input dataout_tready,
  input [63:0] fcin_tdata, input fcin_tlast, input fcin_tvalid, output fcin_tready,
  // To CE
  input [63:0] str_src_tdata, input str_src_tlast, input str_src_tvalid, output str_src_tready
);

   wire [63:0] str_src_tdata_int;
   wire        str_src_tlast_int, str_src_tvalid_int, str_src_tready_int;

  generate
    if (USE_GATE) begin
      axi_packet_gate #(.WIDTH(64), .SIZE(MTU)) axi_packet_gate (
        .clk(clk), .reset(reset), .clear(clear),
        .i_tdata(str_src_tdata), .i_tlast(str_src_tlast), .i_terror(1'b0), .i_tvalid(str_src_tvalid), .i_tready(str_src_tready),
        .o_tdata(str_src_tdata_int), .o_tlast(str_src_tlast_int), .o_tvalid(str_src_tvalid_int), .o_tready(str_src_tready_int));
    end else begin
      assign str_src_tdata_int = str_src_tdata;
      assign str_src_tlast_int = str_src_tlast;
      assign str_src_tvalid_int = str_src_tvalid;
      assign str_src_tready = str_src_tready_int;
    end
  endgenerate

  source_flow_control #(
    .SR_FLOW_CTRL_EN(SR_FLOW_CTRL_EN),
    .SR_FLOW_CTRL_WINDOW_SIZE(SR_FLOW_CTRL_WINDOW_SIZE),
    .SR_FLOW_CTRL_PKT_LIMIT(SR_FLOW_CTRL_PKT_LIMIT))
  source_flow_control (
    .clk(clk), .reset(reset), .clear(clear),
    .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
    .fc_tdata(fcin_tdata), .fc_tlast(fcin_tlast), .fc_tvalid(fcin_tvalid), .fc_tready(fcin_tready),
    .in_tdata(str_src_tdata_int), .in_tlast(str_src_tlast_int), .in_tvalid(str_src_tvalid_int), .in_tready(str_src_tready_int),
    .out_tdata(dataout_tdata), .out_tlast(dataout_tlast), .out_tvalid(dataout_tvalid), .out_tready(dataout_tready),
    .busy(),
    .debug());

endmodule // noc_output_port
module axi_round_and_clip
#(
  parameter WIDTH_IN=24,
  parameter WIDTH_OUT=16,
  parameter CLIP_BITS=3,
  parameter FIFOSIZE=1)  // FIFOSIZE = 1, single output register
(
  input clk, input reset,
  input [WIDTH_IN-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
  output [WIDTH_OUT-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready
);

  wire [WIDTH_OUT+CLIP_BITS-1:0] int_tdata;
  wire int_tlast, int_tvalid, int_tready;

  generate
    if (WIDTH_IN == WIDTH_OUT+CLIP_BITS) begin
       assign int_tdata    = i_tdata;
       assign int_tlast    = i_tlast;
       assign int_tvalid   = i_tvalid;
       assign i_tready     = int_tready;
    end else begin
      axi_round #(
        .WIDTH_IN(WIDTH_IN), .WIDTH_OUT(WIDTH_OUT+CLIP_BITS),
        .round_to_nearest(1), .FIFOSIZE(FIFOSIZE))
      axi_round (
        .clk(clk), .reset(reset),
        .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
        .o_tdata(int_tdata), .o_tlast(int_tlast), .o_tvalid(int_tvalid), .o_tready(int_tready));
    end

    if (CLIP_BITS == 0) begin
      assign o_tdata    = int_tdata;
      assign o_tlast    = int_tlast;
      assign o_tvalid   = int_tvalid;
      assign int_tready = o_tready;
    end else begin
      axi_clip #(
        .WIDTH_IN(WIDTH_OUT+CLIP_BITS), .WIDTH_OUT(WIDTH_OUT),
        .FIFOSIZE(FIFOSIZE))
      axi_clip (
        .clk(clk), .reset(reset),
        .i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
        .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
    end
  endgenerate

endmodule // round_and_clip
module split_complex
  #(parameter WIDTH=16)
   (input [WIDTH*2-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH-1:0] oi_tdata, output oi_tlast, output oi_tvalid, input oi_tready,
    output [WIDTH-1:0] oq_tdata, output oq_tlast, output oq_tvalid, input oq_tready,
    output error);

   assign oi_tdata = i_tdata[WIDTH*2-1:WIDTH];
   assign oq_tdata = i_tdata[WIDTH-1:0];

   assign oi_tlast = i_tlast;
   assign oq_tlast = i_tlast;

   assign oi_tvalid = i_tvalid;
   assign oq_tvalid = i_tvalid;

   assign i_tready = oi_tready;

   assign  error = oi_tready ^ oq_tready;
   
endmodule // split_complex
module delay_type3
  #(parameter FIFOSIZE=5,
    parameter MAX_LEN_LOG2=10,
    parameter WIDTH=16,
    parameter DELAY_VAL=0)
   (input clk, input reset, input clear,
    input [MAX_LEN_LOG2-1:0] len,
    input [WIDTH-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   wire [WIDTH-1:0]    int_tdata;
   wire 	       int_tlast, int_tvalid, int_tready;
   
   axi_fifo #(.WIDTH(WIDTH+1), .SIZE(MAX_LEN_LOG2)) sample_fifo
     (.clk(clk), .reset(reset), .clear(clear),
      .i_tdata({i_tlast,i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
      .o_tdata({int_tlast,int_tdata}), .o_tvalid(int_tvalid), .o_tready(int_tready));

   delay_type2 #(.MAX_LEN_LOG2(MAX_LEN_LOG2), .WIDTH(WIDTH), .DELAY_VAL(DELAY_VAL)) delay
     (.clk(clk), .reset(reset), .clear(clear),
      .len(len),
      .i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
      .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));

endmodule // delay_type3
module counter
  #(parameter WIDTH=16)
   (input clk, input reset, input clear,
    input [WIDTH:0] max,
    input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   reg [WIDTH-1:0]     count;
   
   wire 	       do_it = o_tready & i_tvalid;
   wire 	       done = (count >= (max-1));
   
   always @(posedge clk)
     if(reset | clear)
       count <= 0;
     else
       if(do_it)
	 if( done | i_tlast )
	   count <= 0;
   	 else
	   count <= count + 1;
   
   assign o_tdata = count;
   assign o_tlast = done | i_tlast;
   assign o_tvalid = i_tvalid;
   assign i_tready = do_it;
   
endmodule // counter
module peak_finder
  #(parameter SCALAR=131072)
   (input clk, input reset, input clear,
    input [31:0] i0_tdata, input i0_tlast, input i0_tvalid, output i0_tready,        // power measurment
    input [31:0] i1_tdata, input i1_tlast, input i1_tvalid, output i1_tready,        // cross power mag/phase
    output [31:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

    wire [15:0] i_phase_tdata = i1_tdata[31:16];
    wire [15:0] i_mag_tdata = i1_tdata[15:0];

    // moved contents of threshold_scaled functionality here
    wire signed [31:0] scaled_input = (i_mag_tdata-1)*SCALAR;
    wire signed [31:0] difference = scaled_input - i0_tdata;
    wire thresh_met = difference > 0;

    // internal registers
    reg [63:0] counter;
    reg [7:0] debounce_counter;
    reg [15:0] max_val;
    reg [15:0] max_phase;
    reg [63:0] max_idx;

    // output registers
    reg found_burst;
    reg [15:0] burst_offset;
    reg [15:0] burst_phase;
   wire        do_op;

    // search for peaks durring (thresh_met = 1) periods
    // debounce the thresh_met line
    // send a notification and burst time/frequency downstream
    always @(posedge (clk))
        if(reset | clear)   
          begin
            counter <= 0;
            debounce_counter <= 0;
            max_val <= 0;
            max_phase <= 0;
            max_idx <= 0;
            found_burst <= 0;
            burst_offset <= 0;
            burst_phase <= 0;
          end
        else
            if(do_op)
              begin
                counter <= counter + 1;
                if(thresh_met | (debounce_counter > 0))
                  begin
                    if(thresh_met)
                        debounce_counter <= 5;
                    else
                        debounce_counter <= debounce_counter - 1;
                    if(i_mag_tdata > max_val)
                      begin
                        max_val <= i_mag_tdata;
                        max_phase <= i_phase_tdata;
                        max_idx <= counter;
                      end
                  end
                else
                  // we have concluded on a peak if max_idx > 0
                  if(max_idx > 0)
                    begin
                        found_burst <= 1;
                        burst_offset <= (counter - max_idx);
                        burst_phase <= max_phase;
                        max_val <= 0;
                        max_idx <= 0;
                    end
                  else
                    begin
                      found_burst <= 0;
                      burst_offset <= 0;
                      burst_phase <= 0;
                    end
              end

    assign o_tdata = {burst_phase, burst_offset};
    assign o_tlast = found_burst;

   assign do_op = (i0_tvalid & i1_tvalid & o_tready);
   
   assign o_tvalid = i0_tvalid & i1_tvalid;
   
    assign i0_tready = do_op;
    assign i1_tready = do_op;

endmodule // peak_finder
module axi_clip_unsigned
  #(parameter WIDTH_IN=24,
    parameter WIDTH_OUT=16,
    parameter FIFOSIZE=0)  // leave at 0 for a normal single flop
   (input clk, input reset,
    input [WIDTH_IN-1:0] i_tdata, input i_tlast, input i_tvalid, output i_tready,
    output [WIDTH_OUT-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

   wire overflow = |i_tdata[WIDTH_IN-1:WIDTH_OUT];

   wire [WIDTH_OUT-1:0] out = overflow ? {1'b0,{(WIDTH_OUT-1){1'b1}}} : i_tdata[WIDTH_OUT-1:0];

   axi_fifo #(.WIDTH(WIDTH_OUT+1), .SIZE(FIFOSIZE)) flop
     (.clk(clk), .reset(reset), .clear(1'b0),
      .i_tdata({i_tlast, out}), .i_tvalid(i_tvalid), .i_tready(i_tready),
      .o_tdata({o_tlast, o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready),
      .occupied(), .space());

endmodule // clip