data/full_repos/permissive/427281804/FPU/verilog/FIR.v
1: b'%Warning-WIDTH: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:84: Operator ASSIGNDLY expects 8 bits on the Assign RHS, but Assign RHS\'s VARREF \'S9_SLEEP_LEN\' generates 32 or 9 bits.\n                                                                         : ... In instance W4823_FIR\n  cycle_cnt_r   <= S9_SLEEP_LEN;\n                ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:147: Operator EQ expects 32 or 9 bits on the LHS, but LHS\'s VARREF \'cycle_cnt_r\' generates 8 bits.\n                                                                          : ... In instance W4823_FIR\n   if(cycle_cnt_r == S9_SLEEP_LEN-1 ) begin\n                  ^~\n%Error: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:232: Cannot find file containing module: \'icgc\'\n icgc u_cgc_cmem(.CK(clk_fast),.E(first_cycle_r|dmem_clk_en),.ECK(cmem_clk));\n ^~~~\n        ... Looked in:\n             data/full_repos/permissive/427281804/FPU/verilog,data/full_repos/permissive/427281804/icgc\n             data/full_repos/permissive/427281804/FPU/verilog,data/full_repos/permissive/427281804/icgc.v\n             data/full_repos/permissive/427281804/FPU/verilog,data/full_repos/permissive/427281804/icgc.sv\n             icgc\n             icgc.v\n             icgc.sv\n             obj_dir/icgc\n             obj_dir/icgc.v\n             obj_dir/icgc.sv\n%Error: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:406: Cannot find file containing module: \'FPALU\'\n FPALU u_fpalu(\n ^~~~~\n%Warning-WIDTH: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:420: Operator ASSIGNW expects 16 bits on the Assign RHS, but Assign RHS\'s VARREF \'alu_y_29i\' generates 29 bits.\n                                                                          : ... In instance W4823_FIR\nassign dout     = alu_y_29i;\n                ^\n%Error: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:430: Cannot find file containing module: \'SP_DMEM\'\n SP_DMEM u_dmem (\n ^~~~~~~\n%Error: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:440: Cannot find file containing module: \'SP_CMEM\'\n SP_CMEM u_cmem (\n ^~~~~~~\n%Error: data/full_repos/permissive/427281804/FPU/verilog/FIR.v:449: Cannot find file containing module: \'SP_REGF\'\n SP_REGF u_regf (\n ^~~~~~~\n%Error: Exiting due to 5 error(s), 3 warning(s)\n'
module W4823_FIR(
	input           rst_n,
	input           clk_slow,
	input           clk,
	input [15:0]    din,
	input           valid_in,
	input [15:0]    cin,
	input [5:0]     caddr,
	input           cload,
	output [15:0]   dout,
	output          valid,
	output [28:0]   dout_29i
);




`define USE_VENDOR_MEMORY





wire       clk_fast   = clk;
wire       clk_fast_n = ~clk_fast;
reg [5:0]  ss_r;
reg [7:0]  cycle_cnt_r;
reg        first_cycle_r;

localparam S0_LOAD_LEN     = 1;
localparam S1_MUL_NDAV_LEN = 4;
localparam S2_MUL_LEN      = 59;
localparam S3_ACC_THRU_LEN = 5;
localparam S4_ACC_LEN      = 59;
localparam S5_ACC_P1_LEN   = 5;
localparam S6_ACC_P2_LEN   = 3;
localparam S7_ACC_P3_LEN   = 1;
localparam S8_ACC_P4_LEN   = 7;
localparam SA_RESERVED_LEN = 1;
localparam SB_DINLATCH_LEN = 1;
localparam S9_SLEEP_LEN    = 256-S0_LOAD_LEN-S1_MUL_NDAV_LEN-S2_MUL_LEN-S3_ACC_THRU_LEN-S4_ACC_LEN-S5_ACC_P1_LEN-S6_ACC_P2_LEN-S7_ACC_P3_LEN-S8_ACC_P4_LEN-SA_RESERVED_LEN-SB_DINLATCH_LEN;



`define S0_LOAD      6'b000001
`define S1_MUL_NDAV  6'b000011
`define S2_MUL       6'b000010
`define S3_ACC_THRU  6'b000110
`define S4_ACC       6'b000100
`define S5_ACC_P1    6'b001100
`define S6_ACC_P2    6'b001000
`define S7_ACC_P3    6'b011000
`define S8_ACC_P4    6'b010000
`define S9_SLEEP     6'b110000
`define SA_RESERVED  6'b100000
`define SB_DINLATCH  6'b100001

wire cycle_load      = ~ss_r[1] & ss_r[0] &~ss_r[5];
wire cycle_mul_ndav  =  ss_r[0] & ss_r[1];
wire cycle_mul       = ~ss_r[2] & ss_r[1] &~ss_r[0];
wire cycle_acc_thru  =  ss_r[1] & ss_r[2];
wire cycle_acc       = ~ss_r[3] & ss_r[2] &~ss_r[1];
wire cycle_acc_p1    =  ss_r[3] & ss_r[2];
wire cycle_acc_p2    = ~ss_r[4] & ss_r[3] &~ss_r[2];
wire cycle_acc_p3    =  ss_r[4] & ss_r[3];
wire cycle_acc_p4    = ~ss_r[5] & ss_r[4] &~ss_r[3];
wire cycle_sleep     =  ss_r[5] & ss_r[4];
wire cycle_reserved  = ~ss_r[0] & ss_r[5] &~ss_r[4];
wire cycle_dinlatch  =  ss_r[0] & ss_r[5];


assign valid = cycle_sleep;


always @(posedge clk_fast or negedge rst_n) begin
	if(~rst_n) begin

		ss_r          <= `S9_SLEEP;
		cycle_cnt_r   <= S9_SLEEP_LEN;
		first_cycle_r <= 1'b1;
	end else begin
		case(ss_r)
		`S0_LOAD:
			ss_r <= `S1_MUL_NDAV;
		`S1_MUL_NDAV: begin
			if(cycle_cnt_r==S1_MUL_NDAV_LEN-1) begin	
				ss_r        <= `S2_MUL;
				cycle_cnt_r <= 0;	
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S2_MUL: begin
			if(cycle_cnt_r==S2_MUL_LEN-1) begin
				ss_r        <= `S3_ACC_THRU;
				cycle_cnt_r <= 0;	
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S3_ACC_THRU: begin
			if(cycle_cnt_r==S3_ACC_THRU_LEN-1) begin
				ss_r        <= `S4_ACC;
				cycle_cnt_r <= 0;
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S4_ACC: begin
			if(cycle_cnt_r==S4_ACC_LEN-1) begin
				ss_r        <= `S5_ACC_P1;
				cycle_cnt_r <= 0;	
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S5_ACC_P1: begin
			if(cycle_cnt_r == S5_ACC_P1_LEN-1) begin
				ss_r        <= `S6_ACC_P2;
				cycle_cnt_r <= 0; 
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S6_ACC_P2: begin
			if(cycle_cnt_r == S6_ACC_P2_LEN-1) begin
				ss_r        <= `S7_ACC_P3;
				cycle_cnt_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S7_ACC_P3: begin
			if(cycle_cnt_r == S7_ACC_P3_LEN-1) begin
				ss_r            <= `S8_ACC_P4;
				cycle_cnt_r     <= 0;
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S8_ACC_P4: begin
			if(cycle_cnt_r == S8_ACC_P4_LEN-1) begin
				ss_r        <= `S9_SLEEP;
				cycle_cnt_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S9_SLEEP: begin
			if(cycle_cnt_r == S9_SLEEP_LEN-1 ) begin
				ss_r        <= `SA_RESERVED;
				cycle_cnt_r <= 0;
				first_cycle_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`SA_RESERVED: ss_r  <= `SB_DINLATCH;
		`SB_DINLATCH: ss_r  <= `S0_LOAD;

		endcase
	end
end







reg cycle_load_dly_r;	
always @(negedge clk_fast) begin
	if(cycle_load) cycle_load_dly_r <= 1;
	else           cycle_load_dly_r <= 0;
end



wire        cmem_wr = first_cycle_r&clk_slow;
wire        cmem_clk;
wire [5:0]  cmem_addr;
reg  [5:0]  cmem_addr_r;
wire [15:0] cmem_din_fp16 = cin;

reg         dmem_wr_r;
wire        dmem_clk;
wire        dmem_clk_en;

reg [5:0]	dmem_addr_r;


wire        din_latch;
reg [15:0]  din_r;

assign cmem_addr = (first_cycle_r) ? caddr : cmem_addr_r;

wire dmem_cmem_rst = dmem_wr_r&~dmem_clk;
reg cycle_dinlatch_pulse_r;

always @(posedge cycle_dinlatch or negedge clk_fast) begin
	if(~clk_fast) cycle_dinlatch_pulse_r <= 0;
	else          cycle_dinlatch_pulse_r <= 1;
end

always @(posedge cycle_dinlatch) begin
	din_r <= din;
end

wire cycle_dinlatch_n = ~cycle_dinlatch_pulse_r;
always @(posedge clk_fast_n) begin
	if(cycle_acc_thru) cmem_addr_r <= -1;
	else if(cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul) 
		cmem_addr_r <= cmem_addr_r + 1;
end

always @(negedge clk_fast) begin
	if(cycle_dinlatch&&dmem_wr_r==0) dmem_wr_r <= 1;
	else                             dmem_wr_r <= 0;
end

wire alu_clk_en = ~cycle_sleep;
wire alu_clk;
assign din_latch = cycle_dinlatch_pulse_r;
assign dmem_clk_en = (cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul);

always @(negedge clk_fast or negedge rst_n) begin
	if(~rst_n)	         dmem_addr_r <= 0;
	else if(dmem_clk_en) dmem_addr_r <= dmem_addr_r + 1;
end


`ifdef USE_VENDOR_CGC


`else
	icgc u_cgc_cmem(.CK(clk_fast),.E(first_cycle_r|dmem_clk_en),.ECK(cmem_clk));
	assign alu_clk  = clk_fast & alu_clk_en;
	assign dmem_clk = dmem_clk_en & clk_fast;

`endif







reg cycle_mul_dly1_r;
wire cycle_mul_neg = ~cycle_mul;
always @(posedge alu_clk or negedge cycle_mul_neg) begin
	if(~cycle_mul_neg)   cycle_mul_dly1_r <= 1;
	else                 cycle_mul_dly1_r <= 0;
end
 
reg          regf_wr_r;
reg [5:0]    regf_addr_r;
wire regf_clken    = (regf_wr_r|cycle_acc_thru|cycle_acc);
wire regf_clk      = (regf_clken & alu_clk);
wire regf_clk_flip = ~(cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul|cycle_mul_dly1_r);
wire regf_clk_f    = regf_clk ^ regf_clk_flip;
always @(negedge alu_clk) begin
	if(cycle_mul) regf_wr_r = 1;
	else          regf_wr_r = 0;
end
always @(negedge regf_clk_f) begin
	if(~regf_clken) 
		regf_addr_r <= 0;
	else if (cycle_acc_thru)
		regf_addr_r <= 0;
	else 
		regf_addr_r <= regf_addr_r + 1;
end






localparam FP29i_SIZE = 29;
localparam FP16_SIZE  = 16;
wire [FP16_SIZE-1 :0] dmem_q_fp16;
wire [FP16_SIZE-1 :0] cmem_q_fp16;
wire [FP29i_SIZE-1:0] regf_q_fp29i;


wire [FP29i_SIZE-1:0] alumux_din_fp16;
wire [FP29i_SIZE-1:0] alumux_dmem_fp16;
wire [FP29i_SIZE-1:0] alumux_cmem_fp16;
wire [FP29i_SIZE-1:0] alumux_self_fp29i; 
wire [FP29i_SIZE-1:0] alumux_regf_fp29i;
wire [FP29i_SIZE-1:0] alumux_acc_fp29i;


reg  [FP29i_SIZE-1:0] alu_a_29i_r;
reg  [FP29i_SIZE-1:0] alu_b_29i_r;
reg  [FP29i_SIZE-1:0] alu_a_29i;
reg  [FP29i_SIZE-1:0] alu_b_29i;
wire                  alu_a_s = alu_a_29i_r[28];
wire [5:0]            alu_a_e = alu_a_29i_r[27:22];
wire [21:0]           alu_a_m = alu_a_29i_r[21:0];
wire                  alu_b_s = alu_b_29i_r[28];
wire [5:0]            alu_b_e = alu_b_29i_r[27:22];
wire [21:0]           alu_b_m = alu_b_29i_r[21:0];
wire                  alu_y_s;
wire [5:0]	          alu_y_e;
wire [21:0]	          alu_y_m;
wire [FP29i_SIZE-1:0] alu_y_29i = {alu_y_s, alu_y_e, alu_y_m};


reg  [FP29i_SIZE-1:0] alumux_dly_r;
always @(posedge alu_clk) begin
	if(cycle_acc_p1|cycle_acc_p3) alumux_dly_r <= alumux_self_fp29i;
	else                          alumux_dly_r <= alumux_dly_r;
end


reg [1:0] alu_opcode;
reg [1:0] alu_opcode_r;
always @(posedge alu_clk) begin
	alu_a_29i_r  <= alu_a_29i;
	alu_b_29i_r  <= alu_b_29i;
	alu_opcode_r <= alu_opcode;
end

reg  [FP29i_SIZE-1:0] alumux_self_fp29i_r; 
always @(negedge alu_clk) begin
	alumux_self_fp29i_r <= alumux_self_fp29i;
end




assign alumux_din_fp16   = {din_r[15],       1'bx, din_r[14:10],       {12{1'bx}}, din_r[9:0]      };
assign alumux_dmem_fp16  = {dmem_q_fp16[15], 1'bx, dmem_q_fp16[14:10], {12{1'bx}}, dmem_q_fp16[9:0]};
assign alumux_self_fp29i = alu_y_29i;

assign alumux_cmem_fp16  = {cmem_q_fp16[15], 1'bx, cmem_q_fp16[14:10], {12{1'bx}}, cmem_q_fp16[9:0]};
assign alumux_regf_fp29i = regf_q_fp29i;

`ifdef DEBUGINFO
integer dbg_alumux_state;
`endif
always @* begin
	alu_a_29i = 0;
	alu_b_29i = 0;
	alu_opcode = 2'bxx;


	if(cycle_dinlatch|cycle_load) begin
		alu_a_29i = alumux_din_fp16;
		alu_b_29i = alumux_cmem_fp16;
		alu_opcode = 2'b10;
		`ifdef DEBUGINFO
			dbg_alumux_state = 0;
		`endif
	end
	if(cycle_mul_ndav|cycle_mul) begin
		alu_a_29i = alumux_dmem_fp16;
		alu_b_29i = alumux_cmem_fp16;
		alu_opcode = 2'b10;
		`ifdef DEBUGINFO
			dbg_alumux_state = 1;
		`endif
	end         

	if(cycle_acc_thru) begin		
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = {28'b0,1'b0};
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 2;
		`endif
	end 

	if(cycle_acc) begin
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = alumux_regf_fp29i;
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 3;
		`endif
	end 

	if(cycle_acc_p1|cycle_acc_p2|cycle_acc_p3|cycle_acc_p4) begin
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = alumux_dly_r;
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 4;
		`endif
	end
end


`ifdef USE_DUMMY_ALU
	FPALU_dummy u_fpalu(
		.clk               (alu_clk   ),
		.opcode            (alu_opcode_r),
		.din_uni_a_sgn     (alu_a_s   ),
		.din_uni_a_exp     (alu_a_e   ),
		.din_uni_a_man_dn  (alu_a_m   ),
		.din_uni_b_sgn     (alu_b_s   ),
		.din_uni_b_exp     (alu_b_e   ),
		.din_uni_b_man_dn  (alu_b_m   ),
		.dout_uni_y_sgn    (alu_y_s   ),
		.dout_uni_y_exp    (alu_y_e   ),
		.dout_uni_y_man_dn (alu_y_m   )
	);
`else
	FPALU u_fpalu(
		.clk               (alu_clk   ),
		.opcode            (alu_opcode_r),
		.din_uni_a_sgn     (alu_a_s   ),
		.din_uni_a_exp     (alu_a_e   ),
		.din_uni_a_man_dn  (alu_a_m   ),
		.din_uni_b_sgn     (alu_b_s   ),
		.din_uni_b_exp     (alu_b_e   ),
		.din_uni_b_man_dn  (alu_b_m   ),
		.dout_uni_y_sgn    (alu_y_s   ),
		.dout_uni_y_exp    (alu_y_e   ),
		.dout_uni_y_man_dn (alu_y_m   )
	);
`endif
assign dout     = alu_y_29i;
assign dout_29i = alu_y_29i;





`ifdef USE_VENDOR_MEMORY
	

	SP_DMEM u_dmem (
		.Q   (dmem_q_fp16),
		.CLK (clk_fast  ),
		.CEN (~(dmem_clk_en)),
		.WEN (~dmem_wr_r ),
		.A   (dmem_addr_r),
		.D   (din_r        )
	);


	SP_CMEM u_cmem (
		.Q   (cmem_q_fp16),
		.CLK (clk_fast^first_cycle_r),
		.CEN (~(first_cycle_r|dmem_clk_en)),
		.WEN (~cmem_wr   ),
		.A   (cmem_addr  ),
		.D   (cmem_din_fp16)
	);

	SP_REGF u_regf (
		.Q   (regf_q_fp29i ),
		.CLK (regf_clk_f    ),
		.CEN (~rst_n       ),
		.WEN (~regf_wr_r   ),
		.A   (regf_addr_r  ),
		.D   (alumux_self_fp29i_r)
	);
`else

	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(16)
	) u_dmem (
		.clk  (dmem_clk   ),
		.addr (dmem_addr_r),
		.din  (din_r        ),
		.wr   (dmem_wr_r  ),
		.qout (dmem_q_fp16)
	);


	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(16)
	) u_cmem (
		.clk  (cmem_clk      ),
		.addr (cmem_addr     ),
		.din  (cmem_din_FP16),
		.wr   (cmem_wr       ),
		.qout (cmem_q_fp16  )
	);


	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(29)
	) u_regf (
		.clk  (regf_clk         ),
		.addr (regf_addr_r      ),
		.din  (alumux_self_fp29i),
		.wr   (regf_wr_r        ),
		.qout (regf_q_fp29i     )
	);
`endif

`ifdef DEBUGINFO
integer dbg_alu_clk_cnt;
reg     dbg_alu_outrdy;
always @(posedge alu_clk or posedge cycle_dinlatch) begin
	if(cycle_dinlatch) begin
		dbg_alu_clk_cnt <= 0;
		dbg_alu_outrdy <= 0;
	end else begin          
		dbg_alu_clk_cnt <= dbg_alu_clk_cnt + 1;
		if(dbg_alu_clk_cnt==3)  
			dbg_alu_outrdy <= 1;
	end
end 
`endif

endmodule
module W4823_FIR(
	input           rst_n,
	input           clk_slow,
	input           clk,
	input [15:0]    din,
	input           valid_in,
	input [15:0]    cin,
	input [5:0]     caddr,
	input           cload,
	output [15:0]   dout,
	output          valid,
	output [28:0]   dout_29i
);





`define USE_VENDOR_MEMORY





wire       clk_fast   = clk;
wire       clk_fast_n = ~clk_fast;
reg [5:0]  ss_r;
reg [7:0]  cycle_cnt_r;
reg        first_cycle_r;

localparam S0_LOAD_LEN     = 1;
localparam S1_MUL_NDAV_LEN = 4;
localparam S2_MUL_LEN      = 59;
localparam S3_ACC_THRU_LEN = 5;
localparam S4_ACC_LEN      = 59;
localparam S5_ACC_P1_LEN   = 5;
localparam S6_ACC_P2_LEN   = 3;
localparam S7_ACC_P3_LEN   = 1;
localparam S8_ACC_P4_LEN   = 7;
localparam SA_RESERVED_LEN = 1;
localparam SB_DINLATCH_LEN = 1;
localparam S9_SLEEP_LEN    = 256-S0_LOAD_LEN-S1_MUL_NDAV_LEN-S2_MUL_LEN-S3_ACC_THRU_LEN-S4_ACC_LEN-S5_ACC_P1_LEN-S6_ACC_P2_LEN-S7_ACC_P3_LEN-S8_ACC_P4_LEN-SA_RESERVED_LEN-SB_DINLATCH_LEN;



`define S0_LOAD      6'b000001
`define S1_MUL_NDAV  6'b000011
`define S2_MUL       6'b000010
`define S3_ACC_THRU  6'b000110
`define S4_ACC       6'b000100
`define S5_ACC_P1    6'b001100
`define S6_ACC_P2    6'b001000
`define S7_ACC_P3    6'b011000
`define S8_ACC_P4    6'b010000
`define S9_SLEEP     6'b110000
`define SA_RESERVED  6'b100000
`define SB_DINLATCH  6'b100001

wire cycle_load      = ~ss_r[1] & ss_r[0] &~ss_r[5];
wire cycle_mul_ndav  =  ss_r[0] & ss_r[1];
wire cycle_mul       = ~ss_r[2] & ss_r[1] &~ss_r[0];
wire cycle_acc_thru  =  ss_r[1] & ss_r[2];
wire cycle_acc       = ~ss_r[3] & ss_r[2] &~ss_r[1];
wire cycle_acc_p1    =  ss_r[3] & ss_r[2];
wire cycle_acc_p2    = ~ss_r[4] & ss_r[3] &~ss_r[2];
wire cycle_acc_p3    =  ss_r[4] & ss_r[3];
wire cycle_acc_p4    = ~ss_r[5] & ss_r[4] &~ss_r[3];
wire cycle_sleep     =  ss_r[5] & ss_r[4];
wire cycle_reserved  = ~ss_r[0] & ss_r[5] &~ss_r[4];
wire cycle_dinlatch  =  ss_r[0] & ss_r[5];


assign valid = cycle_sleep;


always @(posedge clk_fast or negedge rst_n) begin
	if(~rst_n) begin

		ss_r          <= `S9_SLEEP;
		cycle_cnt_r   <= S9_SLEEP_LEN;
		first_cycle_r <= 1'b1;
	end else begin
		case(ss_r)
		`S0_LOAD:
			ss_r <= `S1_MUL_NDAV;
		`S1_MUL_NDAV: begin
			if(cycle_cnt_r==S1_MUL_NDAV_LEN-1) begin	
				ss_r        <= `S2_MUL;
				cycle_cnt_r <= 0;	
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S2_MUL: begin
			if(cycle_cnt_r==S2_MUL_LEN-1) begin
				ss_r        <= `S3_ACC_THRU;
				cycle_cnt_r <= 0;	
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S3_ACC_THRU: begin
			if(cycle_cnt_r==S3_ACC_THRU_LEN-1) begin
				ss_r        <= `S4_ACC;
				cycle_cnt_r <= 0;
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S4_ACC: begin
			if(cycle_cnt_r==S4_ACC_LEN-1) begin
				ss_r        <= `S5_ACC_P1;
				cycle_cnt_r <= 0;	
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S5_ACC_P1: begin
			if(cycle_cnt_r == S5_ACC_P1_LEN-1) begin
				ss_r        <= `S6_ACC_P2;
				cycle_cnt_r <= 0; 
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S6_ACC_P2: begin
			if(cycle_cnt_r == S6_ACC_P2_LEN-1) begin
				ss_r        <= `S7_ACC_P3;
				cycle_cnt_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S7_ACC_P3: begin
			if(cycle_cnt_r == S7_ACC_P3_LEN-1) begin
				ss_r            <= `S8_ACC_P4;
				cycle_cnt_r     <= 0;
			end else 
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S8_ACC_P4: begin
			if(cycle_cnt_r == S8_ACC_P4_LEN-1) begin
				ss_r        <= `S9_SLEEP;
				cycle_cnt_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`S9_SLEEP: begin
			if(cycle_cnt_r == S9_SLEEP_LEN-1 ) begin
				ss_r        <= `SA_RESERVED;
				cycle_cnt_r <= 0;
				first_cycle_r <= 0;
			end else
				cycle_cnt_r <= cycle_cnt_r + 1'b1;
		end
		`SA_RESERVED: ss_r  <= `SB_DINLATCH;
		`SB_DINLATCH: ss_r  <= `S0_LOAD;

		endcase
	end
end







reg cycle_load_dly_r;	
always @(negedge clk_fast) begin
	if(cycle_load) cycle_load_dly_r <= 1;
	else           cycle_load_dly_r <= 0;
end



wire        cmem_wr = first_cycle_r&clk_slow;
wire        cmem_clk;
wire [5:0]  cmem_addr;
reg  [5:0]  cmem_addr_r;
wire [15:0] cmem_din_fp16 = cin;

reg         dmem_wr_r;
wire        dmem_clk;
wire        dmem_clk_en;

reg [5:0]	dmem_addr_r;


wire        din_latch;
reg [15:0]  din_r;

assign cmem_addr = (first_cycle_r) ? caddr : cmem_addr_r;

wire dmem_cmem_rst = dmem_wr_r&~dmem_clk;
reg cycle_dinlatch_pulse_r;

always @(posedge cycle_dinlatch or negedge clk_fast) begin
	if(~clk_fast) cycle_dinlatch_pulse_r <= 0;
	else          cycle_dinlatch_pulse_r <= 1;
end

always @(posedge cycle_dinlatch) begin
	din_r <= din;
end

wire cycle_dinlatch_n = ~cycle_dinlatch_pulse_r;
always @(posedge clk_fast_n) begin
	if(cycle_acc_thru) cmem_addr_r <= -1;
	else if(cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul) 
		cmem_addr_r <= cmem_addr_r + 1;
end

always @(negedge clk_fast) begin
	if(cycle_dinlatch&&dmem_wr_r==0) dmem_wr_r <= 1;
	else                             dmem_wr_r <= 0;
end

wire alu_clk_en = ~cycle_sleep;
wire alu_clk;
assign din_latch = cycle_dinlatch_pulse_r;
assign dmem_clk_en = (cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul);

always @(negedge clk_fast or negedge rst_n) begin
	if(~rst_n)	         dmem_addr_r <= 0;
	else if(dmem_clk_en) dmem_addr_r <= dmem_addr_r + 1;
end


`ifdef USE_VENDOR_CGC


`else
	icgc u_cgc_cmem(.CK(clk_fast),.E(first_cycle_r|dmem_clk_en),.ECK(cmem_clk));
	assign alu_clk  = clk_fast & alu_clk_en;
	assign dmem_clk = dmem_clk_en & clk_fast;

`endif







reg cycle_mul_dly1_r;
wire cycle_mul_neg = ~cycle_mul;
always @(posedge alu_clk or negedge cycle_mul_neg) begin
	if(~cycle_mul_neg)   cycle_mul_dly1_r <= 1;
	else                 cycle_mul_dly1_r <= 0;
end
 
reg          regf_wr_r;
reg [5:0]    regf_addr_r;
wire regf_clken    = (regf_wr_r|cycle_acc_thru|cycle_acc);
wire regf_clk      = (regf_clken & alu_clk);
wire regf_clk_flip = ~(cycle_dinlatch|cycle_load|cycle_mul_ndav|cycle_mul|cycle_mul_dly1_r);
wire regf_clk_f    = regf_clk ^ regf_clk_flip;
always @(negedge alu_clk) begin
	if(cycle_mul) regf_wr_r = 1;
	else          regf_wr_r = 0;
end
always @(negedge regf_clk_f) begin
	if(~regf_clken) 
		regf_addr_r <= 0;
	else if (cycle_acc_thru)
		regf_addr_r <= 0;
	else 
		regf_addr_r <= regf_addr_r + 1;
end






localparam FP29i_SIZE = 29;
localparam FP16_SIZE  = 16;
wire [FP16_SIZE-1 :0] dmem_q_fp16;
wire [FP16_SIZE-1 :0] cmem_q_fp16;
wire [FP29i_SIZE-1:0] regf_q_fp29i;


wire [FP29i_SIZE-1:0] alumux_din_fp16;
wire [FP29i_SIZE-1:0] alumux_dmem_fp16;
wire [FP29i_SIZE-1:0] alumux_cmem_fp16;
wire [FP29i_SIZE-1:0] alumux_self_fp29i; 
wire [FP29i_SIZE-1:0] alumux_regf_fp29i;
wire [FP29i_SIZE-1:0] alumux_acc_fp29i;


reg  [FP29i_SIZE-1:0] alu_a_29i_r;
reg  [FP29i_SIZE-1:0] alu_b_29i_r;
reg  [FP29i_SIZE-1:0] alu_a_29i;
reg  [FP29i_SIZE-1:0] alu_b_29i;
wire                  alu_a_s = alu_a_29i_r[28];
wire [5:0]            alu_a_e = alu_a_29i_r[27:22];
wire [21:0]           alu_a_m = alu_a_29i_r[21:0];
wire                  alu_b_s = alu_b_29i_r[28];
wire [5:0]            alu_b_e = alu_b_29i_r[27:22];
wire [21:0]           alu_b_m = alu_b_29i_r[21:0];
wire                  alu_y_s;
wire [5:0]	          alu_y_e;
wire [21:0]	          alu_y_m;
wire [FP29i_SIZE-1:0] alu_y_29i = {alu_y_s, alu_y_e, alu_y_m};


reg  [FP29i_SIZE-1:0] alumux_dly_r;
always @(posedge alu_clk) begin
	if(cycle_acc_p1|cycle_acc_p3) alumux_dly_r <= alumux_self_fp29i;
	else                          alumux_dly_r <= alumux_dly_r;
end


reg [1:0] alu_opcode;
reg [1:0] alu_opcode_r;
always @(posedge alu_clk) begin
	alu_a_29i_r  <= alu_a_29i;
	alu_b_29i_r  <= alu_b_29i;
	alu_opcode_r <= alu_opcode;
end

reg  [FP29i_SIZE-1:0] alumux_self_fp29i_r; 
always @(negedge alu_clk) begin
	alumux_self_fp29i_r <= alumux_self_fp29i;
end




assign alumux_din_fp16   = {din_r[15],       1'bx, din_r[14:10],       {12{1'bx}}, din_r[9:0]      };
assign alumux_dmem_fp16  = {dmem_q_fp16[15], 1'bx, dmem_q_fp16[14:10], {12{1'bx}}, dmem_q_fp16[9:0]};
assign alumux_self_fp29i = alu_y_29i;

assign alumux_cmem_fp16  = {cmem_q_fp16[15], 1'bx, cmem_q_fp16[14:10], {12{1'bx}}, cmem_q_fp16[9:0]};
assign alumux_regf_fp29i = regf_q_fp29i;

`ifdef DEBUGINFO
integer dbg_alumux_state;
`endif
always @* begin
	alu_a_29i = 0;
	alu_b_29i = 0;
	alu_opcode = 2'bxx;


	if(cycle_dinlatch|cycle_load) begin
		alu_a_29i = alumux_din_fp16;
		alu_b_29i = alumux_cmem_fp16;
		alu_opcode = 2'b10;
		`ifdef DEBUGINFO
			dbg_alumux_state = 0;
		`endif
	end
	if(cycle_mul_ndav|cycle_mul) begin
		alu_a_29i = alumux_dmem_fp16;
		alu_b_29i = alumux_cmem_fp16;
		alu_opcode = 2'b10;
		`ifdef DEBUGINFO
			dbg_alumux_state = 1;
		`endif
	end         

	if(cycle_acc_thru) begin		
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = {28'b0,1'b0};
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 2;
		`endif
	end 

	if(cycle_acc) begin
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = alumux_regf_fp29i;
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 3;
		`endif
	end 

	if(cycle_acc_p1|cycle_acc_p2|cycle_acc_p3|cycle_acc_p4) begin
		alu_a_29i = alumux_self_fp29i;
		alu_b_29i = alumux_dly_r;
		alu_opcode = 2'b11;
		`ifdef DEBUGINFO
			dbg_alumux_state = 4;
		`endif
	end
end


`ifdef USE_DUMMY_ALU
	FPALU_dummy u_fpalu(
		.clk               (alu_clk   ),
		.opcode            (alu_opcode_r),
		.din_uni_a_sgn     (alu_a_s   ),
		.din_uni_a_exp     (alu_a_e   ),
		.din_uni_a_man_dn  (alu_a_m   ),
		.din_uni_b_sgn     (alu_b_s   ),
		.din_uni_b_exp     (alu_b_e   ),
		.din_uni_b_man_dn  (alu_b_m   ),
		.dout_uni_y_sgn    (alu_y_s   ),
		.dout_uni_y_exp    (alu_y_e   ),
		.dout_uni_y_man_dn (alu_y_m   )
	);
`else
	FPALU u_fpalu(
		.clk               (alu_clk   ),
		.opcode            (alu_opcode_r),
		.din_uni_a_sgn     (alu_a_s   ),
		.din_uni_a_exp     (alu_a_e   ),
		.din_uni_a_man_dn  (alu_a_m   ),
		.din_uni_b_sgn     (alu_b_s   ),
		.din_uni_b_exp     (alu_b_e   ),
		.din_uni_b_man_dn  (alu_b_m   ),
		.dout_uni_y_sgn    (alu_y_s   ),
		.dout_uni_y_exp    (alu_y_e   ),
		.dout_uni_y_man_dn (alu_y_m   )
	);
`endif
assign dout     = alu_y_29i;
assign dout_29i = alu_y_29i;





`ifdef USE_VENDOR_MEMORY
	

	SP_DMEM u_dmem (
		.Q   (dmem_q_fp16),
		.CLK (clk_fast  ),
		.CEN (~(dmem_clk_en)),
		.WEN (~dmem_wr_r ),
		.A   (dmem_addr_r),
		.D   (din_r        )
	);


	SP_CMEM u_cmem (
		.Q   (cmem_q_fp16),
		.CLK (clk_fast^first_cycle_r),
		.CEN (~(first_cycle_r|dmem_clk_en)),
		.WEN (~cmem_wr   ),
		.A   (cmem_addr  ),
		.D   (cmem_din_fp16)
	);

	SP_REGF u_regf (
		.Q   (regf_q_fp29i ),
		.CLK (regf_clk_f    ),
		.CEN (~rst_n       ),
		.WEN (~regf_wr_r   ),
		.A   (regf_addr_r  ),
		.D   (alumux_self_fp29i_r)
	);
`else

	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(16)
	) u_dmem (
		.clk  (dmem_clk   ),
		.addr (dmem_addr_r),
		.din  (din_r        ),
		.wr   (dmem_wr_r  ),
		.qout (dmem_q_fp16)
	);


	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(16)
	) u_cmem (
		.clk  (cmem_clk      ),
		.addr (cmem_addr     ),
		.din  (cmem_din_FP16),
		.wr   (cmem_wr       ),
		.qout (cmem_q_fp16  )
	);


	sp_sram #(
		.ADDR_WIDTH(6),
		.DATA_WIDTH(29)
	) u_regf (
		.clk  (regf_clk         ),
		.addr (regf_addr_r      ),
		.din  (alumux_self_fp29i),
		.wr   (regf_wr_r        ),
		.qout (regf_q_fp29i     )
	);
`endif

`ifdef DEBUGINFO
integer dbg_alu_clk_cnt;
reg     dbg_alu_outrdy;
always @(posedge alu_clk or posedge cycle_dinlatch) begin
	if(cycle_dinlatch) begin
		dbg_alu_clk_cnt <= 0;
		dbg_alu_outrdy <= 0;
	end else begin          
		dbg_alu_clk_cnt <= dbg_alu_clk_cnt + 1;
		if(dbg_alu_clk_cnt==3)  
			dbg_alu_outrdy <= 1;
	end
end 
`endif

endmodule