# 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
```