# controller of transducer in Verilog & Testbench maincode ```=v module transducer_control_demo( input i_clk, input i_reset, output reg o_ch1 //之後還要output更多的channel(同時) ); //=================================================== //parameter //=================================================== parameter para_initial_delay_time=5, //ms para_clk_count=100,//個數 //state的參數 p_idle_state=1'd0, p_generate_clk_state=1'd1, p_stop=2'd2; //=================================================== //regs //=================================================== //客製化 reg [31:0] p_initial_delay_time=para_initial_delay_time; reg [31:0] p_clk_count=para_clk_count; //en reg en_idle_state,en_generate_clk_state; //state regs reg [1:0]state, next_state; //counters reg [31:0] generate_clk_counter; //需要改善寬度 (參數化) reg [9:0] div_counter;//數1000 (50Mhz=>50khz除頻器要除1000) reg [31:0] idle_state_counter;//需要改善寬度 (參數化) //div_clk reg div_50khz_clk; //flags reg initial_delay_time_flag; reg clk_count_flag; //clk_count 要數幾個clk才能滿足第一個idle state reg [31:0] clk_count; //用parameter 去做? //=================================================== //idle_state //=================================================== //完成之後flag設為1 讓狀態機進行下一個state //除頻成50khz的counter always@(posedge i_clk) begin if (i_reset) div_counter<=1'd0; else if (en_idle_state)begin if (div_counter==10'd1000) div_counter<=1'd0; else div_counter<=div_counter+1'd1; end else div_counter<=1'd0; end //除頻 always@(posedge i_clk) begin if (i_reset) div_50khz_clk<=1'd0; else if (div_counter==9'd499) div_50khz_clk<=~div_50khz_clk; else div_50khz_clk<=div_50khz_clk; end //用50khz的clk去數 p_initial_delay_time //要數幾個clk? always@(*)begin clk_count=(p_initial_delay_time*50); end //計數 always@(posedge div_50khz_clk or posedge i_reset) begin if (i_reset) begin idle_state_counter<=1'd0; //initial_delay_time_flag<=1'd0; end else if (en_idle_state) begin if (idle_state_counter==clk_count-1)begin idle_state_counter<=1'd0; //initial_delay_time_flag<=1'd1; end else begin idle_state_counter<=idle_state_counter+1'd1; //initial_delay_time_flag<=1'd0; end end else begin idle_state_counter<=1'd0; //initial_delay_time_flag<=1'd0; end end // idle_stateflag (用組合邏輯來實現不會有delay) always@(*) begin if (idle_state_counter==clk_count-1) initial_delay_time_flag<=1'd1; else initial_delay_time_flag<=1'd0; end //=================================================== //generate_clk_state //=================================================== always@(posedge i_clk) begin if (i_reset) begin generate_clk_counter<=1'd0; //clk_count_flag<=1'd0; end else if (en_generate_clk_state)begin if (generate_clk_counter==(p_clk_count-1))begin generate_clk_counter<=1'd0; //clk_count_flag<=1'd1; end else begin //clk_count_flag<=1'd0; generate_clk_counter<=generate_clk_counter+1'd1; end end else begin generate_clk_counter<=1'd0; //clk_count_flag<=1'd0; end end //flag 顯示已經產生出我們需要的clk了 // p_generate_clk_state_flag (用組合邏輯來實現不會有delay) always@(*) begin if (generate_clk_counter==(p_clk_count-1)) clk_count_flag<=1'd1; else clk_count_flag<=1'd0; end //=================================================== //fsm //=================================================== always@(posedge i_clk) begin if (i_reset) state<=p_idle_state; else state<=next_state; end always@(*) begin case (state) p_idle_state: if (initial_delay_time_flag) next_state=p_generate_clk_state; else next_state=state; p_generate_clk_state: if (clk_count_flag) next_state=p_stop; else next_state=state; p_stop:next_state=state; default:next_state=p_idle_state; endcase end always@(*) begin case (state) p_idle_state:begin o_ch1=1'd0; en_idle_state=1'd1; en_generate_clk_state=1'd0; end p_generate_clk_state: begin o_ch1=i_clk; en_idle_state=1'd0; en_generate_clk_state=1'd1; end p_stop:begin o_ch1=1'd0; en_idle_state=1'd0; en_generate_clk_state=1'd0; end default :begin o_ch1=1'd0; en_idle_state=1'd1; en_generate_clk_state=1'd0; end endcase end endmodule ``` tb ```=v /* Filename : top_module_test.v Simulator : Quartus II 20.1 ModelSim 2020.1 scription : serial communications protocols testing ckt Release : Aug.17,2021 */ //設定timescale `timescale 10ps/1ps //設定testbench名 module transducer_control_demo_test; //input用reg output用wire reg i_clk,i_reset; wire o_ch1; //引用待測模組 transducer_control_demo t1(.i_reset(i_reset), .i_clk(i_clk), .o_ch1(o_ch1) ); //clk signal initial #0 i_clk=1'b1; always #5 i_clk =~i_clk; //rst input initial begin: in_set_blk #0 i_reset=1'd1; #1 i_reset=1'd0; end //signals initial begin: signals_blks integer i; for (i=0;i<5000;i=i+1) begin #7500 $display (" time=",$time, " idle_state_counter=%d, clk_count=%d, initial_delay_time_flag=%d \n",t1.idle_state_counter, t1.clk_count, t1.initial_delay_time_flag); $display (" time=",$time, " state=%d next_state=%d\n",t1.state,t1.next_state); end #10 $stop; #10 $finish; end endmodule ```