dakies/OSS_Verilog huggingface dataset:
module design_1
   (dp_video_ref_clk_0,
    dp_external_custom_event1_0,
    dp_external_custom_event2_0,
    dp_external_vsync_event_0,
    dp_live_gfx_alpha_in_0,
    dp_live_gfx_pixel1_in_0,
    dp_live_video_de_out_0,
    dp_live_video_in_de_0,
    dp_live_video_in_hsync_0,
    dp_live_video_in_pixel1_0,
    dp_live_video_in_vsync_0,
    dp_video_in_clk_0,
    dp_video_out_hsync_0,
    dp_video_out_pixel1_0,
    dp_video_out_vsync_0,
    pl_clk0_0);
  output dp_video_ref_clk_0;
  input dp_external_custom_event1_0;
  input dp_external_custom_event2_0;
  input dp_external_vsync_event_0;
  input [7:0]dp_live_gfx_alpha_in_0;
  input [35:0]dp_live_gfx_pixel1_in_0;
  output dp_live_video_de_out_0;
  input dp_live_video_in_de_0;
  input dp_live_video_in_hsync_0;
  input [35:0]dp_live_video_in_pixel1_0;
  input dp_live_video_in_vsync_0;
  input dp_video_in_clk_0;
  output dp_video_out_hsync_0;
  output [35:0]dp_video_out_pixel1_0;
  output dp_video_out_vsync_0;
  output pl_clk0_0;

  wire dp_external_custom_event1_0;
  wire dp_external_custom_event2_0;
  wire dp_external_vsync_event_0;
  wire [7:0]dp_live_gfx_alpha_in_0;
  wire [35:0]dp_live_gfx_pixel1_in_0;
  wire dp_live_video_de_out_0;
  wire dp_live_video_in_de_0;
  wire dp_live_video_in_hsync_0;
  wire [35:0]dp_live_video_in_pixel1_0;
  wire dp_live_video_in_vsync_0;
  wire dp_video_in_clk_0;
  wire dp_video_out_hsync_0;
  wire [35:0]dp_video_out_pixel1_0;
  wire dp_video_out_vsync_0;
  wire pl_clk0_0;
  
  
  
    localparam RATE150 = 1000.0/150.00;
    
    reg         reset = 1;
    initial #100 reset = 0;
    
    reg         clk150 = 1'b1;
    always #(RATE150/2.0) clk150 <= ~clk150;
    
    assign pl_clk0_0 = clk150;
    
    
endmodule
module bipolar_stepper_motor_drive
        #(
            parameter   Q_WIDTH         = 16,       // 小数点サイズ
            parameter   MICROSTEP_WIDTH = 12,
            parameter   PAHSE_WIDTH     = 2 + Q_WIDTH
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            
            input   wire                        microstep_en,
            input   wire                        nanostep_en,
            input   wire                        asyc_update_en,
            
            input   wire    [PAHSE_WIDTH-1:0]   phase,
            output  wire                        update,
            
            output  wire                        out_a,
            output  wire                        out_b
        );
    
    
    wire    [1:0]    out_val;
    
    microstep_pwm_control
            #(
                .PAHSE_WIDTH        (2+Q_WIDTH),
                .Q_WIDTH            (Q_WIDTH),
                .OUTPUT_WIDTH       (2),
                .MICROSTEP_WIDTH    (MICROSTEP_WIDTH)
            )
        i_microstep_pwm_control
            (
                .reset              (reset),
                .clk                (clk),
                
                .microstep_en       (microstep_en),
                .nanostep_en        (nanostep_en),
                .asyc_update_en     (asyc_update_en),
                
                .phase              (phase),
                .update             (update),
                
                .out_val            (out_val)
            );
    
    
    reg     [1:0]                   reg_out;
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_out <= 2'b00;
        end
        else begin
            case ( out_val )
            2'd0:   reg_out <= 2'b00;
            2'd1:   reg_out <= 2'b01;
            2'd2:   reg_out <= 2'b11;
            2'd3:   reg_out <= 2'b10;
            endcase
        end
    end
    
    assign out_a = reg_out[0];
    assign out_b = reg_out[1];
    
endmodule
module microstep_pwm_control
        #(
            parameter   PAHSE_WIDTH     = 32,
            parameter   Q_WIDTH         = 16,
            parameter   OUTPUT_WIDTH    = PAHSE_WIDTH - Q_WIDTH,
            parameter   MICROSTEP_WIDTH = 12
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            
            input   wire                        microstep_en,
            input   wire                        nanostep_en,
            input   wire                        asyc_update_en,
            
            input   wire    [PAHSE_WIDTH-1:0]   phase,
            output  wire                        update,
            
            output  wire    [OUTPUT_WIDTH-1:0]  out_val
        );
    
    localparam NANOSTEP_WIDTH = Q_WIDTH > MICROSTEP_WIDTH ? Q_WIDTH - MICROSTEP_WIDTH : 1;
    
    
    function [PAHSE_WIDTH-1:0]  microstep_cnv(input [MICROSTEP_WIDTH-1:0] microstep);
    begin
        if ( Q_WIDTH > MICROSTEP_WIDTH ) begin
            microstep_cnv = microstep << (Q_WIDTH - MICROSTEP_WIDTH);
        end
        else begin
            microstep_cnv = microstep >> (MICROSTEP_WIDTH - Q_WIDTH);
        end
    end
    endfunction
    
    function [PAHSE_WIDTH-1:0]  nanostep_cnv(input [NANOSTEP_WIDTH-1:0] nanostep);
    integer i;
    begin
        nanostep_cnv = 0;
        if ( Q_WIDTH > MICROSTEP_WIDTH ) begin
            for ( i = 0; i < NANOSTEP_WIDTH; i = i+1 ) begin
                nanostep_cnv[i] = nanostep[NANOSTEP_WIDTH-1 - i];
            end
        end
    end
    endfunction
    
    
    reg     [MICROSTEP_WIDTH-1:0]   st0_micro_counter;
    reg     [NANOSTEP_WIDTH-1:0]    st0_nano_counter;
    wire    [PAHSE_WIDTH-1:0]       st0_micro_step = microstep_en ? microstep_cnv(st0_micro_counter) : 0;
    wire    [PAHSE_WIDTH-1:0]       st0_nano_step  = nanostep_en  ? nanostep_cnv(st0_nano_counter)   : 0;
    reg     [PAHSE_WIDTH-1:0]       st0_phase;
    reg     [PAHSE_WIDTH-1:0]       st1_phase;
    
    always @(posedge clk) begin
        if ( reset ) begin
            st0_micro_counter <= {MICROSTEP_WIDTH{1'b0}};
            st0_nano_counter  <= {NANOSTEP_WIDTH{1'b0}};
            st0_phase         <= {PAHSE_WIDTH{1'b0}};
            st1_phase         <= {PAHSE_WIDTH{1'b0}};
        end
        else begin
            // stage 0
            if ( update || asyc_update_en ) begin
                st0_phase <= phase;
            end
            st0_micro_counter <= st0_micro_counter + 1'b1;
            if ( update ) begin
                st0_nano_counter <= st0_nano_counter + 1'b1;
            end
            
            // stage 1
            st1_phase <= st0_phase + st0_micro_step + st0_nano_step;
        end
    end
    
    assign update = (st0_micro_counter == {MICROSTEP_WIDTH{1'b1}});
    
    assign out_val = (st1_phase >> Q_WIDTH);
    
endmodule
module zybo_clk
        (
            input   wire            in_clk125,
            
            output  wire            vga_hsync,
            output  wire            vga_vsync,
            output  wire    [4:0]   vga_r,
            output  wire    [5:0]   vga_g,
            output  wire    [4:0]   vga_b,
            
            input   wire    [3:0]   push_sw,
            input   wire    [3:0]   dip_sw,
            output  wire    [3:0]   led
        );
    
    wire    reset;
    wire    clk;
    
    assign reset = push_sw[0];
    
    clk_wiz_0 
        i_clk_wiz_0
            (
                .clk_in1    (in_clk125),
                .clk_out1   (clk)
            );
    
    
    reg     [31:0]      counter;
    reg     [3:0]       led_out;
    
    always @(posedge clk or posedge reset) begin
        if ( reset ) begin
            led_out <= 4'b0000;
            counter <= 0;
        end
        else begin
            counter <= counter + 1;
            if ( counter >= 25000000-1 ) begin
                counter <= 0;
                led_out <= led_out + 1;
            end
        end
    end
    
    assign led = led_out;
    
    
endmodule
module zybo_sw
        (
            input   wire            in_clk125,
            
            output  wire            vga_hsync,
            output  wire            vga_vsync,
            output  wire    [4:0]   vga_r,
            output  wire    [5:0]   vga_g,
            output  wire    [4:0]   vga_b,
            
            input   wire    [3:0]   push_sw,
            input   wire    [3:0]   dip_sw,
            output  wire    [3:0]   led
        );
    
    
    assign led = dip_sw ^ push_sw;
    
    
endmodule
module zybo_led
        (
            input   wire            in_clk125,
            
            output  wire            vga_hsync,
            output  wire            vga_vsync,
            output  wire    [4:0]   vga_r,
            output  wire    [5:0]   vga_g,
            output  wire    [4:0]   vga_b,
            
            input   wire    [3:0]   push_sw,
            input   wire    [3:0]   dip_sw,
            output  wire    [3:0]   led
        );
    
    wire    reset = push_sw[0];
    wire    clk   = in_clk125;
    
    
    reg     [31:0]      counter;
    reg     [3:0]       led_out;
    
    always @(posedge clk or posedge reset) begin
        if ( reset ) begin
            led_out <= 4'b0000;
            counter <= 0;
        end
        else begin
            counter <= counter + 1;
            if ( counter >= 125000000-1 ) begin
                counter <= 0;
                led_out <= led_out + 1;
            end
        end
    end
    
    assign led = led_out;
    
    
endmodule
module jelly_gpu_alu_mul_acm
		(
			input	wire					reset,
			input	wire					clk,
			
			input	wire	[31:0]			s_src0,
			input	wire	[31:0]			s_src1,
			input	wire					s_operation,
			input	wire					s_last,
			input	wire					s_valid,
			output	wire					s_ready,
			
			output	wire	[31:0]			m_dst,
			output	wire					m_valid,
			input	wire					m_ready
		);
	
	wire	[31:0]		mul_src0;
	wire	[31:0]		mul_src1;
	wire	[31:0]		mul_tdata;
	wire				mul_tlast;
	wire				mul_tvalid;
	wire				mul_tready;
	
	assign mul_src0[31:0] = s_src0[31:0];
	
	assign mul_src1[31]   = s_src1[31] ^ s_operation;
	assign mul_src1[30:0] = s_src1[30:0];
	
	jelly_gpu_float_mul
		i_gpu_float_mul
			(
				.aclk					(clk),
				.aresetn				(~reset),
				
				.s_axis_a_tdata			(mul_src0),
				.s_axis_a_tlast			(s_last),
				.s_axis_a_tvalid		(s_valid),
				.s_axis_a_tready		(s_ready),
				
				.s_axis_b_tdata			(mul_src1),
				.s_axis_b_tvalid		(s_valid),
				.s_axis_b_tready		(),
				
				.m_axis_result_tdata	(mul_tdata),
				.m_axis_result_tlast	(mul_tlast),
				.m_axis_result_tvalid	(mul_tvalid),
				.m_axis_result_tready	(mul_tready)
			);
	
	
	wire				acm_tlast;
	wire				acm_tvalid;
	wire				acm_tready;
	
	jelly_gpu_float_acm
		i_gpu_float_acm
			(
				.aclk					(clk),
				.aresetn				(~reset),
				
				.s_axis_a_tdata			(mul_tvalid ? mul_tdata : 32'd0),
				.s_axis_a_tlast			(mul_tvalid ? mul_tlast : 1'b1),
				.s_axis_a_tvalid		(mul_tvalid),
				.s_axis_a_tready		(mul_tready),
				
				.m_axis_result_tdata	(m_dst),
				.m_axis_result_tlast	(acm_tlast),
				.m_axis_result_tvalid	(acm_tvalid),
				.m_axis_result_tready	(acm_tready)
			);
	
	assign acm_tready = acm_tlast ? m_ready : 1'b1;
	
	assign m_valid    = (acm_tvalid & acm_tlast);
	
	
endmodule
module jelly_gpu_register_file
		#(
			parameter	ADDR_WIDTH = 6,
			parameter	DATA_WIDTH = 32,
			parameter	DOUT_REGS0 = 1,
			parameter	DOUT_REGS1 = 1,
			parameter	MODE0      = "WRITE_FIRST",
			parameter	MODE1      = "WRITE_FIRST",
			parameter	RAM_TYPE   = "distributed"
		)
		(
			input	wire						reset,
			input	wire						clk,
			
			// read port
			input	wire						port0_en,
			input	wire	[ADDR_WIDTH-1:0]	port0_addr,
			output	wire	[DATA_WIDTH-1:0]	port0_rdata,
			
			// read port
			input	wire						port1_en,
			input	wire	[ADDR_WIDTH-1:0]	port1_addr,
			output	wire	[DATA_WIDTH-1:0]	port1_rdata,
			
			// write port
			input	wire						port2_we,
			input	wire	[ADDR_WIDTH-1:0]	port2_addr,
			input	wire	[DATA_WIDTH-1:0]	port2_wdata
		);
	
	jelly_ram_dualport
			#(
				.ADDR_WIDTH		(ADDR_WIDTH),
				.DATA_WIDTH		(DATA_WIDTH),
				.RAM_TYPE		(RAM_TYPE),
				.DOUT_REGS0		(DOUT_REGS0),
				.DOUT_REGS1		(0),
				.MODE0			(MODE0),
				.MODE1			(MODE0)
			)
		i_ram_dualport_0
			(
				.clk0			(clk),
				.en0			(port0_en),
				.regcke0		(port0_en),
				.we0			(1'b0),
				.addr0			(port0_addr),
				.din0			({DATA_WIDTH{1'b0}}),
				.dout0			(port0_rdata),
				
				.clk1			(clk),
				.en1			(port2_we),
				.regcke1		(1'b0),
				.we1			(port2_we),
				.addr1			(port2_addr),
				.din1			(port2_wdata),
				.dout1			()
			);
	
		jelly_ram_dualport
			#(
				.ADDR_WIDTH		(ADDR_WIDTH),
				.DATA_WIDTH		(DATA_WIDTH),
				.RAM_TYPE		(RAM_TYPE),
				.DOUT_REGS0		(DOUT_REGS1),
				.DOUT_REGS1		(0),
				.MODE0			(MODE1),
				.MODE1			(MODE1)
			)
		i_ram_dualport_1
			(
				.clk0			(clk),
				.en0			(port1_en),
				.regcke0		(port1_en),
				.we0			(1'b0),
				.addr0			(port1_addr),
				.din0			({DATA_WIDTH{1'b0}}),
				.dout0			(port1_rdata),
				
				.clk1			(clk),
				.en1			(port2_we),
				.regcke1		(1'b0),
				.we1			(port2_we),
				.addr1			(port2_addr),
				.din1			(port2_wdata),
				.dout1			()
			);
	
endmodule
module tb_float_step();
	localparam	RATE = 1000.0/200.0;
	
	reg		clk = 1'b1;
	always #(RATE/2.0) clk = ~clk;
	
	reg		reset = 1'b1;
	initial #(RATE*100) reset = 1'b0;
	
	
	initial begin
		$dumpfile("tb_top.vcd");
		$dumpvars(0, tb_float_step);
	
	#10000
		$finish;
	end
	
	function [31:0] double_to_float(input [63:0] in_double);
	begin
		double_to_float[31]    = in_double[63];
		double_to_float[30:23] = in_double[63:52] - 1023 + 127;
		double_to_float[22:0]  = in_double[51:29];
	end
	endfunction
	
	function [63:0] float_to_double(input [31:0] in_float);
	begin
		float_to_double        = 0;
		float_to_double[63]    = in_float[31];
		float_to_double[62:52] = in_float[30:23] - 127 + 1023;
		float_to_double[51:29] = in_float[22:0];
	end
	endfunction
	
	
	reg		[31:0]		param_init;
	reg		[31:0]		param_step;
	reg					set_param = 1'b0;
	reg					increment = 1'b0;
	reg					valid     = 1'b0;
	
	wire	[31:0]		out_data;
	wire				out_valid;
	
	jelly_float_step
		i_float_step
			(
				.clk			(clk),
				.stage_cke		({6{1'b1}}),
				
				.param_init		(param_init),
				.param_step		(param_step),
				
				.set_param		(valid & set_param),
				.increment		(valid & increment),
				
				.out_data		(out_data)
			);
	
	
	initial begin
//		$display("%f %f", 1.0, $bitstoreal(float_to_double(double_to_float($realtobits(1.0)))) );
//		$display("%f %f", 1.2, $bitstoreal(float_to_double(double_to_float($realtobits(1.2)))) );
//		$display("%f %f", 1.3, $bitstoreal(float_to_double(double_to_float($realtobits(1.3)))) );
//		$display("%f %f", -1.4, $bitstoreal(float_to_double(double_to_float($realtobits(-1.4)))) );
		
		#200
		
		@(negedge clk)
			param_init = double_to_float($realtobits(1.25));
			param_step = double_to_float($realtobits(-0.25));
			set_param  = 1'b1;
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			param_init = 32'hxxxx_xxxx;
			param_step = 32'hxxxx_xxxx;
			set_param  = 1'b0;
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
			
		@(negedge clk)
			increment  = 1'b1;
			valid      = 1'b1;
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)
		@(negedge clk)

		@(negedge clk)
			increment  = 1'b0;
			valid      = 1'b0;
		
		@(negedge clk)
		@(negedge clk)
		#1000

		$finish;
	end
	
	
	
	always @(posedge clk) begin
		if ( out_valid ) begin
			$display("%f", $bitstoreal(float_to_double(out_data)));
		end
	end
	
	
endmodule
module generate_projective_xy
		#(
			parameter	EXP_WIDTH   = 8,
			parameter	FRAC_WIDTH  = 23,
			parameter	FLOAT_WIDTH = 1 + EXP_WIDTH + FRAC_WIDTH,	// sign + exp + frac
			
			parameter	DST_X_WIDTH = 10,
			parameter	DST_Y_WIDTH = 10,
			parameter	DST_X_NUM   = 640,
			parameter	DST_Y_NUM   = 480,
			parameter	SRC_X_WIDTH = 10,
			parameter	SRC_Y_WIDTH = 10,
			parameter	SRC_X_NUM   = 640,
			parameter	SRC_Y_NUM   = 480
		)
		(
			input	wire						reset,
			input	wire						clk,
			input	wire						cke,

			input	wire	[FLOAT_WIDTH-1:0]	matrix00,
			input	wire	[FLOAT_WIDTH-1:0]	matrix01,
			input	wire	[FLOAT_WIDTH-1:0]	matrix02,
			input	wire	[FLOAT_WIDTH-1:0]	matrix10,
			input	wire	[FLOAT_WIDTH-1:0]	matrix11,
			input	wire	[FLOAT_WIDTH-1:0]	matrix12,
			input	wire	[FLOAT_WIDTH-1:0]	matrix20,
			input	wire	[FLOAT_WIDTH-1:0]	matrix21,
			input	wire	[FLOAT_WIDTH-1:0]	matrix22,
			
			output	wire						m_frame_start,
			output	wire						m_line_end,
			output	wire						m_range_out,
			output	wire	[SRC_X_WIDTH-1:0]	m_x,
			output	wire	[SRC_Y_WIDTH-1:0]	m_y,
			output	wire						m_valid,
			input	wire						m_ready
		);
	
	reg		[DST_X_WIDTH-1:0]		reg_x;
	reg		[DST_Y_WIDTH-1:0]		reg_y;
	reg								reg_frame_start;
	reg								reg_line_end;
	reg		[DST_X_WIDTH-1:0]		reg_valid;
	wire							in_ready;
	
	always @(posedge clk) begin
		if ( reset ) begin
			reg_x            <= {DST_X_WIDTH{1'b0}};
			reg_y            <= {DST_Y_WIDTH{1'b0}};
			reg_frame_start  <= 1'b1;
			reg_line_end     <= 1'b0;
			reg_valid        <= 1'b0;
		end
		else if ( cke ) begin
			if ( reg_valid && in_ready ) begin
				reg_frame_start <= 1'b0;
				reg_x           <= reg_x + 1'b1;
				reg_line_end    <= ((reg_x + 1'b1) == (SRC_X_NUM-1));
				if ( reg_line_end ) begin
					reg_x        <= {DST_X_NUM{1'b0}};
					reg_line_end <= 1'b0;
					
					reg_y        <= reg_y + 1'b1;
					if ( reg_y == (SRC_Y_NUM-1) ) begin
						reg_y            <= {DST_Y_NUM{1'b0}};
						reg_frame_start  <= 1'b1;
					end
				end
			end
			reg_valid        <= 1'b1;
		end
	end
	
	
	projective_transformation
			#(
				.EXP_WIDTH		(EXP_WIDTH),
				.FRAC_WIDTH		(FRAC_WIDTH),
				
				.X_WIDTH		(SRC_X_WIDTH+3),
				.Y_WIDTH		(SRC_Y_WIDTH+3),
				.S_X_WIDTH		(DST_X_WIDTH),
				.S_Y_WIDTH		(DST_Y_WIDTH),
				.M_X_WIDTH		(SRC_X_WIDTH),
				.M_Y_WIDTH		(SRC_Y_WIDTH),
				.M_X_NUM		(SRC_X_NUM),
				.M_Y_NUM		(SRC_Y_NUM),
				
				.USER_WIDTH		(2)
			)
		i_projective_transformation
			(
				.reset			(reset),
				.clk			(clk),
				.cke			(cke),
				
				.matrix00		(matrix00),
				.matrix01		(matrix01),
				.matrix02		(matrix02),
				.matrix10		(matrix10),
				.matrix11		(matrix11),
				.matrix12		(matrix12),
				.matrix20		(matrix20),
				.matrix21		(matrix21),
				.matrix22		(matrix22),
				
				.s_user			({reg_frame_start, reg_line_end}),
				.s_x			(reg_x),
				.s_y			(reg_y),
				.s_valid		(reg_valid),
				.s_ready		(in_ready),
				
				.m_user			({m_frame_start, m_line_end}),
				.m_range_out	(m_range_out),
				.m_x			(m_x),
				.m_y			(m_y),
				.m_valid		(m_valid),
				.m_ready		(m_ready)
			);
		
	
endmodule
module oled_control_if
		(
			input	wire				reset,
			input	wire				clk,
			input	wire				clk_x7,
			
			input	wire	[2:1]		olde_bs,
			input	wire				olde_cs_n,
			input	wire				olde_res_n,
			input	wire				olde_dc_n,
			input	wire				olde_wr_n,
			input	wire				olde_e,
			input	wire	[7:0]		olde_d,
			
			input	wire				pwr_en,
			input	wire	[4:0]		gpo,
			
			output	wire	[4:1]		pmod_p,
			output	wire	[4:1]		pmod_n
		);
	
	// assign PMOD
	wire				out_clk_p;
	wire				out_clk_n;
	wire	[2:0]		out_data_p;
	wire	[2:0]		out_data_n;
	
	assign pmod_p[3] = out_clk_p;
	assign pmod_n[3] = out_clk_n;
	assign pmod_p[4] = out_data_p[0];
	assign pmod_n[4] = out_data_n[0];
	assign pmod_p[2] = out_data_p[1];
	assign pmod_n[2] = out_data_n[1];
	assign pmod_p[1] = out_data_p[2];
	assign pmod_n[1] = out_data_n[2];
	
	
	// assign SERDES
	wire	[3*7-1:0]		serdes_data;
	assign serdes_data[4:0] = gpo;
	assign serdes_data[5]   = pwr_en;
	assign serdes_data[6]   = olde_d[7];
	assign serdes_data[7]   = olde_d[6];
	assign serdes_data[8]   = olde_d[5];
	assign serdes_data[9]   = olde_d[4];
	assign serdes_data[10]  = olde_d[3];
	assign serdes_data[11]  = olde_d[2];
	assign serdes_data[12]  = olde_d[1];
	assign serdes_data[13]  = olde_d[0];
	assign serdes_data[14]  = olde_e;
	assign serdes_data[15]  = olde_wr_n;
	assign serdes_data[16]  = olde_dc_n;
	assign serdes_data[17]  = olde_bs[1];
	assign serdes_data[18]  = olde_bs[2];
	assign serdes_data[19]  = olde_cs_n;
	assign serdes_data[20]  = olde_res_n;
	
	serdes_output_to_fin1216
		i_serdes_output_to_fin1216
			(
				.reset			(reset),
				.clk			(clk),
				.clk_x7			(clk_x7),
				
				.in_data		(~serdes_data),
				
				.out_clk_p		(out_clk_p),
				.out_clk_n		(out_clk_n),
				.out_data_p		(out_data_p),
				.out_data_n		(out_data_n)
			);
endmodule
module serdes_output_to_fin1216
		#(
			parameter	N = 3
		)
		(
			input	wire				reset,
			input	wire				clk,
			input	wire				clk_x7,
			
			input	wire	[N*7-1:0]	in_data,
			
			output	wire				out_clk_p,
			output	wire				out_clk_n,
			output	wire	[N-1:0]		out_data_p,
			output	wire	[N-1:0]		out_data_n
		);
	
	assign out_clk_p = clk_x7;
	assign out_clk_n = ~clk_x7;
	assign out_data_p = {N{clk}};
	assign out_data_n = ~{N{clk}};
	
endmodule
module design_1
   (DDR_addr,
    DDR_ba,
    DDR_cas_n,
    DDR_ck_n,
    DDR_ck_p,
    DDR_cke,
    DDR_cs_n,
    DDR_dm,
    DDR_dq,
    DDR_dqs_n,
    DDR_dqs_p,
    DDR_odt,
    DDR_ras_n,
    DDR_reset_n,
    DDR_we_n,
    FIXED_IO_ddr_vrn,
    FIXED_IO_ddr_vrp,
    FIXED_IO_mio,
    FIXED_IO_ps_clk,
    FIXED_IO_ps_porb,
    FIXED_IO_ps_srstb,
    out_clk100,
    out_clk125,
    out_clk200,
    out_clk250,
    out_reset,
    core_clk,
    core_reset,
    in_clk125,
    in_reset);
   inout [14:0]DDR_addr;
   inout [2:0]DDR_ba;
   inout DDR_cas_n;
   inout DDR_ck_n;
   inout DDR_ck_p;
   inout DDR_cke;
   inout DDR_cs_n;
   inout [3:0]DDR_dm;
   inout [31:0]DDR_dq;
   inout [3:0]DDR_dqs_n;
   inout [3:0]DDR_dqs_p;
   inout DDR_odt;
   inout DDR_ras_n;
   inout DDR_reset_n;
   inout DDR_we_n;
   inout FIXED_IO_ddr_vrn;
   inout FIXED_IO_ddr_vrp;
   inout [53:0]FIXED_IO_mio;
   inout FIXED_IO_ps_clk;
   inout FIXED_IO_ps_porb;
   inout FIXED_IO_ps_srstb;
   output out_clk100;
   output out_clk125;
   output out_clk200;
   output out_clk250;
   output core_clk;
   output core_reset;
   output [0:0]out_reset;
   input in_clk125;
   input in_reset;
  
   
	reg			reset  ;//= 1;
	reg			clk100 ;//= 1'b1;
	reg			clk125 ;//= 1'b1;
	reg			clk200 ;//= 1'b1;
	reg			clk250 ;//= 1'b1;
	
	
	assign out_reset             = reset;
	assign out_clk100            = clk100;
	assign out_clk125            = clk125;
	assign out_clk200            = clk200;
	assign out_clk250            = clk250;

   assign core_reset  = reset;
   assign core_clk    = clk200;

   
endmodule
module BUFG(
        input   wire    I,
        output  wire    O
    );

    assign O  = I;

endmodule
module IOBUF(
        input   wire    I,
        input   wire    T,
        output  wire    O,
        inout   wire    IO
    );

    assign O  = IO;
    assign IO = T ? 1'bz : I;

endmodule
module bb_lut
		#(
			parameter					DEVICE = "RTL",
			parameter					N      = 6,
			parameter	[(1<<N)-1:0]	INIT   = {(1<<N){1'b0}}
		)
		(
			input	wire	[N-1:0]		in_data,
			output	wire				out_data
		);
	
	generate
	if ( DEVICE == "7SERIES" && N == 6 ) begin : xilinx_7series
		LUT6
				#(
					.INIT	(INIT)
				)
			i_lut6
				(
					.O		(out_data),
					.I0		(in_data[0]),
					.I1		(in_data[1]),
					.I2		(in_data[2]),
					.I3		(in_data[3]),
					.I4		(in_data[4]),
					.I5		(in_data[5])
				);
	end
	else begin : rtl
		wire	[(1<<N)-1:0]	lut_table = INIT;
		assign out_data = lut_table[in_data];
	end
	endgenerate
	
	
endmodule
module video_oled_cnv
		#(
			parameter	TUSER_WIDTH = 1
		)
		(
			input	wire						aresetn,
			input	wire						aclk,
			input	wire						aclken,
			
			input	wire	[TUSER_WIDTH-1:0]	s_axi4s_tuser,
			input	wire						s_axi4s_tlast,
			input	wire	[23:0]				s_axi4s_tdata,
			input	wire						s_axi4s_tvalid,
			output	wire						s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]	m_axi4s_tuser,
			output	wire						m_axi4s_tlast,
			output	wire	[7:0]				m_axi4s_tdata,
			output	wire						m_axi4s_tvalid,
			input	wire						m_axi4s_tready
		);
	
	
	reg		[2:0]				reg_count;
	always @(posedge aclk) begin
		if ( ~aresetn ) begin
			reg_count <= 0;
		end
		else if ( aclken ) begin
			if ( s_axi4s_tuser[0] && s_axi4s_tvalid && s_axi4s_tready ) begin
				reg_count <= reg_count + 1;
			end
		end
	end
	
	reg		[6:0]				sig_add;
	always @* begin
		case (reg_count)
		3'h0:	sig_add = 7'h00;
		3'h1:	sig_add = 7'h77;
		3'h6:	sig_add = 7'h33;
		3'h7:	sig_add = 7'h44;
		3'h2:	sig_add = 7'h11;
		3'h3:	sig_add = 7'h66;
		3'h4:	sig_add = 7'h22;
		3'h5:	sig_add = 7'h55;
		endcase
	end
	
	reg		[TUSER_WIDTH-1:0]	st0_tuser;
	reg							st0_tlast;
	reg		[23:0]				st0_tdata;
	reg							st0_tvalid;
	
	reg		[TUSER_WIDTH-1:0]	st1_tuser;
	reg							st1_tlast;
	reg		[23:0]				st1_tdata;
	reg							st1_tvalid;
	
	always @(posedge aclk) begin
		if ( aclken && m_axi4s_tready ) begin
			st0_tuser        <= s_axi4s_tuser;
			st0_tlast        <= s_axi4s_tlast;
			st0_tdata        <= s_axi4s_tdata;
			
			st1_tuser        <= st0_tuser;
			st1_tlast        <= st0_tlast;
			st1_tdata[7:0]   <= (st0_tdata[7:0]   >> 1) + sig_add;
			st1_tdata[15:8]  <= (st0_tdata[15:8]  >> 1) + sig_add;
			st1_tdata[23:16] <= (st0_tdata[23:16] >> 1) + sig_add;
		end
	end
	
	always @(posedge aclk) begin
		if ( ~aresetn ) begin
			st0_tvalid <= 1'b0;
			st1_tvalid <= 1'b0;
		end
		else if ( aclken && m_axi4s_tready ) begin
			st0_tvalid <= s_axi4s_tvalid;
			st1_tvalid <= st0_tvalid;
		end
	end
	
	assign s_axi4s_tready   = m_axi4s_tready;
	
	assign m_axi4s_tuser    = st1_tuser;
	assign m_axi4s_tlast    = st1_tlast;
	assign m_axi4s_tdata[0] = st1_tdata[7];		// B3
	assign m_axi4s_tdata[1] = st1_tdata[7];		// B4
	assign m_axi4s_tdata[2] = st1_tdata[15];	// G3
	assign m_axi4s_tdata[3] = st1_tdata[15];	// G4
	assign m_axi4s_tdata[4] = st1_tdata[15];	// G5
	assign m_axi4s_tdata[5] = st1_tdata[23];	// R3
	assign m_axi4s_tdata[6] = st1_tdata[23];	// R4
	assign m_axi4s_tdata[7] = st1_tdata[23];	// R5
	assign m_axi4s_tvalid   = st1_tvalid;
	
	
endmodule
module video_dnn_max_count
		#(
			parameter	NUM_CALSS     = 10,
			parameter	CHANNEL_WIDTH = 8,
			
			parameter	TUSER_WIDTH   = 1,
			parameter	TDATA_WIDTH   = CHANNEL_WIDTH*NUM_CALSS,
			parameter	TNUMBER_WIDTH = 4,
			parameter	TCOUNT_WIDTH  = 4
		)
		(
			input	wire							aresetn,
			input	wire							aclk,
			
			input	wire	[TUSER_WIDTH-1:0]		s_axi4s_tuser,
			input	wire							s_axi4s_tlast,
			input	wire	[TDATA_WIDTH-1:0]		s_axi4s_tdata,
			input	wire							s_axi4s_tvalid,
			output	wire							s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]		m_axi4s_tuser,
			output	wire							m_axi4s_tlast,
			output	wire	[TNUMBER_WIDTH-1:0]		m_axi4s_tnumber,
			output	wire	[TCOUNT_WIDTH-1:0]		m_axi4s_tcount,
			output	wire	[TDATA_WIDTH-1:0]		m_axi4s_tdata,
			output	wire							m_axi4s_tvalid,
			input	wire							m_axi4s_tready
		);
	
	
	wire									cke;
	
	
	// counting
	integer									i, j;
	integer									sum;
	
	reg										counting_tlast;
	reg		[TUSER_WIDTH-1:0]				counting_tuser;
	reg		[TDATA_WIDTH-1:0]				counting_tdata;
	reg		[TCOUNT_WIDTH*NUM_CALSS-1:0]	counting_count;
	reg										counting_valid;
	always @(posedge aclk) begin
		if( ~aresetn ) begin
			counting_tlast  <= 1'bx;
			counting_tuser  <= {TUSER_WIDTH{1'bx}};
			counting_count  <= {(TCOUNT_WIDTH*NUM_CALSS){1'bx}};
			counting_valid  <= 1'b0;
		end
		else if ( cke ) begin
			counting_tlast <= s_axi4s_tlast;
			counting_tuser <= s_axi4s_tuser;
			counting_tdata <= s_axi4s_tdata;
			for ( i = 0; i < NUM_CALSS; i = i+1 ) begin
				sum = 0;
				for ( j = 0; j < CHANNEL_WIDTH; j = j+1 ) begin
					sum = sum + s_axi4s_tdata[j*NUM_CALSS + i];
				end
				counting_count[TCOUNT_WIDTH*i +:TCOUNT_WIDTH] <= sum;
			end
			counting_valid  <= s_axi4s_tvalid;
		end
	end
	
	
	// select max
	jelly_minmax
			#(
				.NUM				(NUM_CALSS),
				.COMMON_USER_WIDTH	(1+TUSER_WIDTH+TDATA_WIDTH),
				.USER_WIDTH			(0),
				.DATA_WIDTH			(TCOUNT_WIDTH),
				.DATA_SIGNED		(0),
				.CMP_MIN			(0),	// minかmaxか
				.CMP_EQ				(0)		// 同値のとき data0 と data1 どちらを優先するか
			)
		i_minmax
			(
				.reset				(~aresetn),
				.clk				(aclk),
				.cke				(cke),
				
				.s_common_user		({counting_tlast, counting_tuser, counting_tdata}),
				.s_user				(1'b0),
				.s_data				(counting_count),
				.s_en				({NUM_CALSS{1'b1}}),
				.s_valid			(counting_valid),
				
				.m_common_user		({m_axi4s_tlast, m_axi4s_tuser, m_axi4s_tdata}),
				.m_user				(),
				.m_data				(m_axi4s_tcount),
				.m_index			(m_axi4s_tnumber),
				.m_en				(),
				.m_valid			(m_axi4s_tvalid)
			);
	
	assign cke = !m_axi4s_tvalid | m_axi4s_tready;
	
	assign s_axi4s_tready = cke;
	
endmodule
module video_dnn_argmax
		#(
			parameter	NUM_CALSS     = 10,
			parameter	COUNT_WIDTH   = 3,
			parameter	CHANNEL_WIDTH = (1 << COUNT_WIDTH) - 1,
			
			parameter	TUSER_WIDTH   = 1,
			parameter	TDATA_WIDTH   = NUM_CALSS * CHANNEL_WIDTH,
			parameter	TNUMBER_WIDTH = 4,
			
			parameter	M_SLAVE_REGS  = 1,
			parameter	M_MASTER_REGS = 1
		)
		(
			input	wire								aresetn,
			input	wire								aclk,
			input	wire								aclken,
			
			input	wire	[TUSER_WIDTH-1:0]			s_axi4s_tuser,
			input	wire								s_axi4s_tlast,
			input	wire	[NUM_CALSS*COUNT_WIDTH-1:0]	s_axi4s_tcount,
			input	wire	[TDATA_WIDTH-1:0]			s_axi4s_tdata,
			input	wire								s_axi4s_tvalid,
			output	wire								s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]			m_axi4s_tuser,
			output	wire								m_axi4s_tlast,
			output	wire	[TNUMBER_WIDTH-1:0]			m_axi4s_tnumber,
			output	wire	[COUNT_WIDTH-1:0]			m_axi4s_tcount,
			output	wire	[TDATA_WIDTH-1:0]			m_axi4s_tdata,
			output	wire								m_axi4s_tvalid,
			input	wire								m_axi4s_tready
		);
	
	
	wire							cke;
	
	wire	[TUSER_WIDTH-1:0]		argmax_tuser;
	wire							argmax_tlast;
	wire	[TNUMBER_WIDTH-1:0]		argmax_tnumber;
	wire	[COUNT_WIDTH-1:0]		argmax_tcount;
	wire	[TDATA_WIDTH-1:0]		argmax_tdata;
	wire							argmax_tvalid;
	
	
	// select max
	jelly_minmax
			#(
				.NUM				(NUM_CALSS),
				.COMMON_USER_WIDTH	(TUSER_WIDTH+1+TDATA_WIDTH),
				.USER_WIDTH			(0),
				.DATA_WIDTH			(COUNT_WIDTH),
				.DATA_SIGNED		(0),
				.CMP_MIN			(0),	// minかmaxか
				.CMP_EQ				(0)		// 同値のとき data0 と data1 どちらを優先するか
			)
		i_minmax
			(
				.reset				(~aresetn),
				.clk				(aclk),
				.cke				(cke),
				
				.s_common_user		({s_axi4s_tuser, s_axi4s_tlast, s_axi4s_tdata}),
				.s_user				(1'b0),
				.s_data				(s_axi4s_tcount),
				.s_en				({NUM_CALSS{1'b1}}),
				.s_valid			(s_axi4s_tvalid),
				
				.m_common_user		({argmax_tuser, argmax_tlast, argmax_tdata}),
				.m_user				(),
				.m_data				(argmax_tcount),
				.m_index			(argmax_tnumber),
				.m_en				(),
				.m_valid			(argmax_tvalid)
			);
	
	// output
	jelly_pipeline_insert_ff
			#(
				.DATA_WIDTH			(TUSER_WIDTH+1+TNUMBER_WIDTH+COUNT_WIDTH+TDATA_WIDTH),
				.SLAVE_REGS			(M_SLAVE_REGS),
				.MASTER_REGS		(M_MASTER_REGS)
			)
		i_pipeline_insert_ff
			(
				.reset				(~aresetn),
				.clk				(aclk),
				.cke				(aclken),
				
				.s_data				({argmax_tuser, argmax_tlast, argmax_tnumber, argmax_tcount, argmax_tdata}),
				.s_valid			(argmax_tvalid),
				.s_ready			(s_axi4s_tready),
				
				.m_data				({m_axi4s_tuser, m_axi4s_tlast, m_axi4s_tnumber, m_axi4s_tcount, m_axi4s_tdata}),
				.m_valid			(m_axi4s_tvalid),
				.m_ready			(m_axi4s_tready),
				
				.buffered			(),
				.s_ready_next		()
			);
	
	assign cke = s_axi4s_tready && aclken;
	
endmodule
module video_dnn_count
		#(
			parameter	NUM_CALSS     = 10,
			parameter	COUNT_WIDTH   = 3,
			parameter	CHANNEL_WIDTH = (1 << COUNT_WIDTH) - 1,
			
			parameter	TUSER_WIDTH   = 1,
			
			parameter	M_SLAVE_REGS  = 1,
			parameter	M_MASTER_REGS = 1,
			
			// local
			parameter	TDATA_WIDTH   = NUM_CALSS * CHANNEL_WIDTH,
			parameter	TCOUNT_WIDTH  = NUM_CALSS * COUNT_WIDTH
		)
		(
			input	wire							aresetn,
			input	wire							aclk,
			input	wire							aclken,
			
			input	wire	[TUSER_WIDTH-1:0]		s_axi4s_tuser,
			input	wire							s_axi4s_tlast,
			input	wire	[TDATA_WIDTH-1:0]		s_axi4s_tdata,
			input	wire							s_axi4s_tvalid,
			output	wire							s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]		m_axi4s_tuser,
			output	wire							m_axi4s_tlast,
			output	wire	[TCOUNT_WIDTH-1:0]		m_axi4s_tcount,
			output	wire	[TDATA_WIDTH-1:0]		m_axi4s_tdata,
			output	wire							m_axi4s_tvalid,
			input	wire							m_axi4s_tready
		);
	
	
	wire						cke;
	
	// counting
	integer						i, j;
	integer						sum;
	
	reg							reg_tlast;
	reg		[TUSER_WIDTH-1:0]	reg_tuser;
	reg		[TDATA_WIDTH-1:0]	reg_tdata;
	reg		[TCOUNT_WIDTH-1:0]	reg_tcount;
	reg							reg_tvalid;
	
	always @(posedge aclk) begin
		if( ~aresetn ) begin
			reg_tlast  <= 1'bx;
			reg_tuser  <= {TUSER_WIDTH{1'bx}};
			reg_tcount <= {TCOUNT_WIDTH{1'bx}};
			reg_tvalid <= 1'b0;
		end
		else if ( cke ) begin
			reg_tlast <= s_axi4s_tlast;
			reg_tuser <= s_axi4s_tuser;
			reg_tdata <= s_axi4s_tdata;
			for ( i = 0; i < NUM_CALSS; i = i+1 ) begin
				sum = 0;
				for ( j = 0; j < CHANNEL_WIDTH; j = j+1 ) begin
					sum = sum + s_axi4s_tdata[j*NUM_CALSS + i];
				end
				reg_tcount[COUNT_WIDTH*i +: COUNT_WIDTH] <= sum;
			end
			reg_tvalid  <= s_axi4s_tvalid;
		end
	end
	
	
	// output
	jelly_pipeline_insert_ff
			#(
				.DATA_WIDTH			(TUSER_WIDTH+1+TCOUNT_WIDTH+TDATA_WIDTH),
				.SLAVE_REGS			(M_SLAVE_REGS),
				.MASTER_REGS		(M_MASTER_REGS)
			)
		i_pipeline_insert_ff
			(
				.reset				(~aresetn),
				.clk				(aclk),
				.cke				(aclken),
				
				.s_data				({reg_tuser, reg_tlast, reg_tcount, reg_tdata}),
				.s_valid			(reg_tvalid),
				.s_ready			(s_axi4s_tready),
				
				.m_data				({m_axi4s_tuser, m_axi4s_tlast, m_axi4s_tcount, m_axi4s_tdata}),
				.m_valid			(m_axi4s_tvalid),
				.m_ready			(m_axi4s_tready),
				
				.buffered			(),
				.s_ready_next		()
			);
	
	assign cke = s_axi4s_tready && aclken;
	
	
endmodule
module LUT6
		#(
			parameter	[63:0]	INIT = {64{1'b0}}
		)
		(
			output	O,
			input	I0,
			input	I1,
			input	I2,
			input	I3,
			input	I4,
			input	I5
		);
	
	wire	[63:0]	lut_table = INIT;
	wire	[5:0]	index = {I5, I4, I3, I2, I1, I0};
	
	assign O = lut_table[index];
	
endmodule
module bldc_pwm
        #(
            parameter   SUB_PAHSE_WIDTH = 12,
            parameter   ASYNC_UPDATE    = 0
        )
        (
            input   wire                            reset,
            input   wire                            clk,
            
            input   wire                            pwm,
            input   wire    [3+SUB_PAHSE_WIDTH-1:0] phase,
            output  wire                            update,
            
            
            output  wire                            pwm_u,
            output  wire                            pwm_v,
            output  wire                            pwm_w,
            output  wire                            en_u,
            output  wire                            en_v,
            output  wire                            en_w
        );
    
    
    reg     [SUB_PAHSE_WIDTH-1:0]   st0_counter;
    reg     [2:0]                   st0_phase_main;
    reg     [SUB_PAHSE_WIDTH-1:0]   st0_phase_sub;
    reg     [2:0]                   st1_phase_main;
    reg     [SUB_PAHSE_WIDTH-1:0]   st1_phase_sub;
    reg     [2:0]                   st2_phase_main;
    reg     [2:0]                   st3_pwm;
    reg     [2:0]                   st3_en;
    
    always @(posedge clk) begin
        if ( reset ) begin
            st0_counter    <= {SUB_PAHSE_WIDTH{1'b0}};
            st0_phase_main <= 3'd0;
            st0_phase_sub  <= {SUB_PAHSE_WIDTH{1'b0}};
            st1_phase_main <= 3'd0;
            st1_phase_sub  <= {SUB_PAHSE_WIDTH{1'b0}};
            st2_phase_main <= 3'd0;
            st3_pwm     <= 3'b001;
        end
        else begin
            // stage 0
            st0_counter <= st0_counter + 1'b1;
            if ( update || ASYNC_UPDATE ) begin
                {st0_phase_main, st0_phase_sub} <= phase;
            end
            
            // stage 1
            if ( pwm ) begin
                {st1_phase_main, st1_phase_sub} <= {st0_phase_main, st0_phase_sub} + st0_counter;
            end
            else begin
                {st1_phase_main, st1_phase_sub} <= {st0_phase_main, st0_phase_sub};
            end
            
            // stage 2
            st2_phase_main <= st1_phase_main > 3'd5 ? 3'd0 : st1_phase_main;
            
            // stage 3
            case (st2_phase_main)
            //                                wvu                wvu
            3'd0:       begin   st3_pwm <= 3'b001;  st3_en <= 3'b011;   end
            3'd1:       begin   st3_pwm <= 3'b100;  st3_en <= 3'b110;   end
            3'd2:       begin   st3_pwm <= 3'b100;  st3_en <= 3'b101;   end
            3'd3:       begin   st3_pwm <= 3'b010;  st3_en <= 3'b011;   end
            3'd4:       begin   st3_pwm <= 3'b010;  st3_en <= 3'b110;   end
            3'd5:       begin   st3_pwm <= 3'b001;  st3_en <= 3'b101;   end
            default:    begin   st3_pwm <= 3'bxxx;  st3_en <= 3'bxxx;   end
            endcase
        end
    end
    
    assign update = (st0_counter == {SUB_PAHSE_WIDTH{1'b1}});
    
    assign {pwm_w, pwm_v, pwm_u} = st3_pwm;
    assign {en_w,  en_v,  en_u}  = st3_en;
    
endmodule
module sin_3phase_pwm
        #(
            parameter   PHASE_WIDTH   = 10,
            parameter   COUNTER_WIDTH = 12
        )
        (
            input   wire                        reset,
            input   wire                        clk,
            
            input   wire    [PHASE_WIDTH-1:0]   in_phase,
            
            output  wire                        pwm_x,
            output  wire                        pwm_y,
            output  wire                        pwm_z
        );
    
    
    wire    [COUNTER_WIDTH-1:0]  x_th;
    wire    [COUNTER_WIDTH-1:0]  y_th;
    wire    [COUNTER_WIDTH-1:0]  z_th;
    sin_3phase_tbl
        i_sin_3phase_tbl
            (
                .reset      (reset),
                .clk        (clk),
                .cke        (1'b1),
                
                .in_phase   (in_phase),
                
                .out_x      (x_th),
                .out_y      (y_th),
                .out_z      (z_th)
            );
    
    
    reg     [COUNTER_WIDTH-1:0] reg_count;
    reg                         reg_pwm_x;
    reg                         reg_pwm_y;
    reg                         reg_pwm_z;
    always @(posedge clk) begin
        if ( reset ) begin
            reg_count <= 0;
            reg_pwm_x <= 1'b0;
            reg_pwm_y <= 1'b0;
            reg_pwm_z <= 1'b0;
        end
        else begin
            reg_count <= reg_count + 1;
            reg_pwm_x <= reg_count < x_th;
            reg_pwm_y <= reg_count < y_th;
            reg_pwm_z <= reg_count < z_th;
        end
    end
    
    assign pwm_x = reg_pwm_x;
    assign pwm_y = reg_pwm_y;
    assign pwm_z = reg_pwm_z;
    
    
endmodule
module tb_bldc_pwm();
    localparam RATE = 1000.0/125.0;
    
    initial begin
        $dumpfile("tb_bldc_pwm.vcd");
        $dumpvars(0, tb_bldc_pwm);
        
    #10000000
        $finish;
    end
    
    reg     reset = 1'b1;
    initial #(RATE*100) reset = 1'b0;
    
    reg     clk = 1'b1;
    always #(RATE/2.0) clk = ~clk;
    
    
    parameter   SUB_PAHSE_WIDTH = 8;
    parameter   PAHSE_WIDTH     = 3 + SUB_PAHSE_WIDTH;
    parameter   PAHSE_MAX     = {3'd5, {SUB_PAHSE_WIDTH{1'b1}}};
    
    
    reg     [PAHSE_WIDTH-1:0]   reg_phase = 0;
    wire                        update;
    wire                        pwm_u;
    wire                        pwm_v;
    wire                        pwm_w;
    wire                        en_u;
    wire                        en_v;
    wire                        en_w;
    
    bldc_pwm
            #(
                .SUB_PAHSE_WIDTH    (SUB_PAHSE_WIDTH),
                .ASYNC_UPDATE       (0)
            )
        i_bldc_pwm
            (
                .reset              (reset),
                .clk                (clk),
                
                .pwm                (1'b0),
                .phase              (reg_phase),
                .update             (update),
                
                .pwm_u              (pwm_u),
                .pwm_v              (pwm_v),
                .pwm_w              (pwm_w),
                .en_u               (en_u),
                .en_v               (en_v),
                .en_w               (en_w)
            );
    
    always @(posedge clk) begin
        if ( reset ) begin
            reg_phase <= 0;
        end
        else begin
            if ( update ) begin
                if ( reg_phase >= PAHSE_MAX ) begin
                    reg_phase <= 0;
                end
                else begin
                    reg_phase <= reg_phase + 1;
                end
            end
        end
    end
    
    
endmodule
module tb_sin_3phase_tbl();
    localparam RATE = 1000.0/125.0;
    
    initial begin
        $dumpfile("tb_sin_3phase_tbl.vcd");
        $dumpvars(0, tb_sin_3phase_tbl);
        
    #100000
        $finish;
    end
    
    reg     reset = 1'b1;
    initial #(RATE*100) reset = 1'b0;
    
    reg     clk = 1'b1;
    always #(RATE/2.0) clk = ~clk;
    
    wire            cke = 1;
    
    reg     [9:0]   in_phase = 0;
    
    wire    [11:0]  out_x;
    wire    [11:0]  out_y;
    wire    [11:0]  out_z;
    
    sin_3phase_tbl
        i_sin_3phase_tbl
            (
                .reset      (reset),
                .clk        (clk),
                .cke        (cke),
                
                .in_phase   (in_phase),
                
                .out_x      (out_x),
                .out_y      (out_y),
                .out_z      (out_z)
            );
    
    always @(posedge clk) begin
        if ( reset ) begin
            in_phase <= 0;
        end
        else if ( cke ) begin
            in_phase <= in_phase + 1;
        end
    end
    
    
endmodule
module tb_top();
    localparam RATE = 1000.0/125.0;
    
    initial begin
        $dumpfile("tb_top.vcd");
        $dumpvars(0, tb_top);
        
    #1000000000
        $finish;
    end
    
    
    reg     reset = 1'b1;
    initial #(RATE*100) reset = 1'b0;
    
    reg     clk = 1'b1;
    always #(RATE/2.0) clk = ~clk;
    
    
    // ----------------------------------
    //  top net
    // ----------------------------------
    
    wire            bldc_u_en;
    wire            bldc_v_en;
    wire            bldc_w_en;
    wire            bldc_u_hl;
    wire            bldc_v_hl;
    wire            bldc_w_hl;
    
    wire    [3:0]       led;
    
    zybo_z7_bldc
            #(
                .SUB_PAHSE_WIDTH    (8)
            )
        i_top
            (
                .in_reset           (reset),
                .in_clk125          (clk),
                
                .dip_sw             (4'b0101),
                
                .bldc_u_en          (bldc_u_en),
                .bldc_v_en          (bldc_v_en),
                .bldc_w_en          (bldc_w_en),
                .bldc_u_hl          (bldc_u_hl),
                .bldc_v_hl          (bldc_v_hl),
                .bldc_w_hl          (bldc_w_hl)
            );
    
    
    wire    [31:0]  en_sum = bldc_u_en + bldc_v_en + bldc_w_en;
    
    
endmodule
module tb_microstep_pwm_control();
    localparam RATE = 1000.0/125.0;
    
    initial begin
        $dumpfile("tb_microstep_pwm_control.vcd");
        $dumpvars(0, tb_microstep_pwm_control);
        
    #10000000
        $finish;
    end
    
    reg     reset = 1'b1;
    initial #(RATE*100) reset = 1'b0;
    
    reg     clk = 1'b1;
    always #(RATE/2.0) clk = ~clk;
    
    
    parameter   PAHSE_WIDTH     = 16;
    parameter   Q_WIDTH         = 12;
    parameter   OUTPUT_WIDTH    = PAHSE_WIDTH - Q_WIDTH;
    parameter   MICROSTEP_WIDTH = 8;
    
    wire                        microstep_en   = 1'b1;
    wire                        nanostep_en    = 1'b1;
    wire                        asyc_update_en = 1'b0;
    
    wire    [PAHSE_WIDTH-1:0]   phase;
    wire                        update;
    
    wire    [OUTPUT_WIDTH-1:0]  out_val;
    
    microstep_pwm_control
            #(
                .PAHSE_WIDTH        (PAHSE_WIDTH),
                .Q_WIDTH            (Q_WIDTH),
                .OUTPUT_WIDTH       (OUTPUT_WIDTH),
                .MICROSTEP_WIDTH    (MICROSTEP_WIDTH)
            )
    microstep_pwm_control
            (
                .reset              (reset),
                .clk                (clk),
                
                .microstep_en       (microstep_en),
                .nanostep_en        (nanostep_en),
                .asyc_update_en     (asyc_update_en),
                
                .phase              (phase),
                .update             (update),
                
                .out_val            (out_val)
            );
    
    
    reg     [PAHSE_WIDTH-1:0]   reg_phase;
    always @(posedge clk) begin
        if ( reset ) begin
            reg_phase <= 0;
        end
        else begin
            if ( update ) begin
                reg_phase <= reg_phase + 7;
            end
        end
    end
    
    assign phase = reg_phase;
    
    
endmodule
module video_mnist_color_core
		#(
			parameter	TUSER_WIDTH   = 1,
			parameter	TDATA_WIDTH   = 24,
			parameter	TNUMBER_WIDTH = 4,
			parameter	TCOUNT_WIDTH  = 4
		)
		(
			input	wire						aresetn,
			input	wire						aclk,
			
			input	wire	[1:0]				param_mode,
			input	wire	[TCOUNT_WIDTH-1:0]	param_th,
			
			input	wire	[TUSER_WIDTH-1:0]	s_axi4s_tuser,
			input	wire						s_axi4s_tlast,
			input	wire	[TNUMBER_WIDTH-1:0]	s_axi4s_tnumber,
			input	wire	[TCOUNT_WIDTH-1:0]	s_axi4s_tcount,
			input	wire	[TDATA_WIDTH-1:0]	s_axi4s_tdata,
			input	wire	[0:0]				s_axi4s_tbinary,
			input	wire						s_axi4s_tvalid,
			output	wire						s_axi4s_tready,
			
			output	wire	[TUSER_WIDTH-1:0]	m_axi4s_tuser,
			output	wire						m_axi4s_tlast,
			output	wire	[TDATA_WIDTH-1:0]	m_axi4s_tdata,
			output	wire						m_axi4s_tvalid,
			input	wire						m_axi4s_tready
		);
	
	
	reg		[TUSER_WIDTH-1:0]		st0_user;
	reg								st0_last;
	reg		[TDATA_WIDTH-1:0]		st0_data;
	reg								st0_en;
	reg		[23:0]					st0_color;
	reg								st0_valid;
	
	reg		[TUSER_WIDTH-1:0]		st1_user;
	reg								st1_last;
	reg		[TDATA_WIDTH-1:0]		st1_data;
	reg								st1_valid;
	
	always @(posedge aclk) begin
		if ( ~aresetn ) begin
			st0_user   <= {TUSER_WIDTH{1'bx}};
			st0_last   <= 1'bx;
			st0_data   <= {TDATA_WIDTH{1'bx}};
			st0_en     <= 1'bx;
			st0_color  <= 24'hxx_xx_xx;
			st0_valid  <= 1'b0;
			
			st1_user   <= {TUSER_WIDTH{1'bx}};
			st1_last   <= 1'bx;
			st1_data   <= {TDATA_WIDTH{1'bx}};
			st1_valid  <= 1'b0;
		end
		else if ( s_axi4s_tready ) begin
			st0_user   <= s_axi4s_tuser;
			st0_last   <= s_axi4s_tlast;
			st0_data   <= param_mode[0] ? {TDATA_WIDTH{s_axi4s_tbinary}} : s_axi4s_tdata;
			st0_en     <= (param_mode[1] && (s_axi4s_tcount >= param_th));
			case ( s_axi4s_tnumber )
			4'd0:		st0_color <= 24'h00_00_00;	// 黒
			4'd1:		st0_color <= 24'h00_00_80;	// 茶
			4'd2:		st0_color <= 24'h00_00_ff;	// 赤
			4'd3:		st0_color <= 24'h4c_b7_ff;	// 橙
			4'd4:		st0_color <= 24'h00_ff_ff;	// 黄
			4'd5:		st0_color <= 24'h00_80_00;	// 緑
			4'd6:		st0_color <= 24'hff_00_00;	// 青
			4'd7:		st0_color <= 24'h80_00_80;	// 紫
			4'd8:		st0_color <= 24'h80_80_80;	// 灰
			4'd9:		st0_color <= 24'hff_ff_ff;	// 白
			default:	st0_color <= 24'hxx_xx_xx;
			endcase
			st0_valid  <= s_axi4s_tvalid;
			
			st1_user   <= st0_user;
			st1_last   <= st0_last;
			st1_data   <= st0_data; // 24'h40_40_40;
			if ( st0_en ) begin
	//			st1_data[ 7: 0] <= (({1'b0, st0_data[ 7: 0]} + {1'b0, st0_color[ 7: 0]}) >> 1);
	//			st1_data[15: 8] <= (({1'b0, st0_data[15: 8]} + {1'b0, st0_color[15: 8]}) >> 1);
	//			st1_data[23:16] <= (({1'b0, st0_data[23:16]} + {1'b0, st0_color[23:16]}) >> 1);
	//			st1_data <= st0_color;
				st1_data <= {st0_color[7:0], st0_color[15:8], st0_color[23:16]};
			end
			st1_valid  <= st0_valid;
		end
	end
	
	assign s_axi4s_tready = (m_axi4s_tready || !m_axi4s_tvalid);
	
	assign m_axi4s_tuser  = st1_user;
	assign m_axi4s_tlast  = st1_last;
	assign m_axi4s_tdata  = st1_data;
	assign m_axi4s_tvalid = st1_valid;
	
endmodule