module cd16 ( input start , input clk, input rst, input [7:0] dat_i, output reg e, output reg rw, output reg di, output reg[7:0] dat ); parameter DIV_WORK_CLOCK = 6600;//²úÉú10kHzÐźſØÖÆlcd.e parameter DIV_WORK_CLOCK_WIDTH = 16; reg init_status ; reg [3:0] inst_state ; reg [3:0] state ; reg [3:0] next_state ; reg [9:0] instruction[3:0] ; reg instruction_set ; reg [3:0] instruction_length ; reg [3:0] instruction_index ; reg[DIV_WORK_CLOCK_WIDTH-1:0] clk_e_counter; wire [9:0] action_struction ; wire p_clk_e;//10kHz assign action_struction = instruction[instruction_length-1-instruction_index] ; assign p_clk_e = (clk_e_counter==0) ? 1'B1:1'B0; always@(posedge clk,negedge rst,posedge instruction_set) begin if(rst == 0) begin e <= 1'B0 ; rw <= 1'B0 ; di <= 1'B0 ; init_status <= 1'b0 ; inst_state <= 4'd0 ; end else if(instruction_set == 1'B1) begin instruction_index <= instruction_length - 1'B1 ; inst_state <= 4'd0 ; init_status<= 1'b1 ; end else if(clk == 1'B1) begin case(inst_state) 4'd0 : //idle begin e <= 0 ; rw <= 0 ; di <= 0 ; if(instruction_length > 0) begin inst_state <= 4'd1 ; end end 4'd1: //get instruction begin di <= action_struction[9] ; rw <= action_struction[8] ; dat <= action_struction[7:0] ; inst_state <= 4'd2 ; end 4'd2: //excute instruction begin e <= 0 ; if(p_clk_e == 1'b1) begin inst_state <= 4'd3 ; end end 4'd3: //excute instruction begin e <= 1'b1 ; if(p_clk_e == 1'b1) begin inst_state <= 4'd4 ; end end 4'd4: //finish instruction begin e <= 0 ; if(p_clk_e == 1'b1) begin if(instruction_index == 1'B0) begin inst_state <= 4'd5 ; init_status <= 1'b0 ; end else begin instruction_index <= instruction_index - 1'b1 ; inst_state <= 4'd1 ; end end end 4'd5: //wait begin if(instruction_length == 0) inst_state <= 4'd0 ; end default: inst_state <= 4'd0 ; endcase end end always@(posedge clk,negedge rst) begin if(rst == 0) begin instruction_length <= 0 ; instruction_set <= 0 ; state <= 4'd1 ; end else if(clk == 1'b1) begin case(state) 4'd0: begin if(start == 1'b1) state <= 4'd4; end 4'd1: begin instruction[0] <= 10'B0000111000 ;//10'b0000110000 instruction[1] <= 10'B0000001110 ;//10'b0000001111 instruction[2] <= 10'B0000000110 ;//10'b0000000110 instruction[3] <= 10'B0000000001 ;//10'b0000000001 instruction_length <= 4 ; instruction_set <= 1'b1 ; next_state <= 4'd0; state <=4'd2 ; end 4'd2: begin instruction_set <= 1'B0 ; if(init_status == 1'b0) begin instruction_length <= 0 ; state <=4'd3 ; end end 4'd3: begin if(start == 1'b0) state <= next_state ; end 4'd4: begin instruction[0] <= {2'b10,dat_i} ; instruction_length <= 1 ; instruction_set <= 1'b1 ; next_state <= 4'd0 ; state <= 4'd2 ; end default: state <= 4'd0 ; endcase end end always@(negedge clk, negedge rst) begin if (rst == 1'B0) clk_e_counter <= 0; else if(clk == 1'B0) begin if (clk_e_counter == DIV_WORK_CLOCK-1'B1) clk_e_counter <= 0; else clk_e_counter <= clk_e_counter+1'B1; end end endmodule