xy2_100.v
module xy2_100(input clk,input tx_init, //当产生上升沿时,开始发数据input wire [15:0]x_pos,input wire [15:0]y_pos,input wire [15:0]z_pos,output clk_2MHz_o,//输出2MHz时钟output sync_o,output x_ch_o,output y_ch_o,output z_ch_o,output tx_done_o
);reg clk_2MHz=1'd1;
reg sync=1'd0;
reg x_ch=1'd0;
reg y_ch=1'd0;
reg z_ch=1'd0;
reg tx_done=1'd0;assign clk_2MHz_o=clk_2MHz;
assign sync_o=sync;
assign x_ch_o=x_ch;
assign y_ch_o=y_ch;
assign z_ch_o=z_ch;
assign tx_done_o=tx_done;reg tx_init1=1'd0;
reg tx_init2=1'd0;
wire start_transaction;
assign start_transaction= tx_init1 & (~tx_init2);reg [5:0]generate_clk_2MHz_cnt=6'd0;
reg [6:0]clk_2MHz_cnt=7'd0;localparam RefFreq=125000000;
localparam XY2_100_2MHz=2000000;
localparam XY2_100_2MHz_Reverse_Cnt=RefFreq/(2*XY2_100_2MHz);
localparam MaxCnt=2*XY2_100_2MHz_Reverse_Cnt+1; always@(posedge clk)
beginif(generate_clk_2MHz_cnt==XY2_100_2MHz_Reverse_Cnt)begingenerate_clk_2MHz_cnt<=6'd0;clk_2MHz<=~clk_2MHz;endelsegenerate_clk_2MHz_cnt<=generate_clk_2MHz_cnt + 6'd1;if(clk_2MHz_cnt==MaxCnt)clk_2MHz_cnt<=7'd0;elseclk_2MHz_cnt<=clk_2MHz_cnt+7'd1;tx_init1<=tx_init;tx_init2<=tx_init1;
endlocalparam Idle=5'd0;
localparam Wait_First_2MHz_Posedge=5'd1;
localparam C2=5'd2;
localparam C1=5'd3;
localparam C0=5'd4;
localparam D15=5'd5;
localparam D14=5'd6;
localparam D13=5'd7;
localparam D12=5'd8;
localparam D11=5'd9;
localparam D10=5'd10;
localparam D9=5'd11;
localparam D8=5'd12;
localparam D7=5'd13;
localparam D6=5'd14;
localparam D5=5'd15;
localparam D4=5'd16;
localparam D3=5'd17;
localparam D2=5'd18;
localparam D1=5'd19;
localparam D0=5'd20;
localparam P=5'd21;reg [4:0]status=Idle;always@(posedge clk)
beginif(status==Idle)begintx_done<=1'd0;if(start_transaction==1'd1)status<=Wait_First_2MHz_Posedge;elsestatus<=status;endelse if(status==Wait_First_2MHz_Posedge)beginif(clk_2MHz_cnt==MaxCnt)beginsync<=1'd1;x_ch<=1'd0;y_ch<=1'd0;z_ch<=1'd0;status<=C2;endelsestatus<=status;endelse if(status==C2)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=1'd0;y_ch<=1'd0;z_ch<=1'd0;status<=C1;endelsestatus<=status;endelse if(status==C1)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=1'd1;y_ch<=1'd1;z_ch<=1'd1;status<=C0;endelsestatus<=status;endelse if(status==C0)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[15];y_ch<=y_pos[15];z_ch<=z_pos[15];status<=D15;endelsestatus<=status;endelse if(status==D15)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[14];y_ch<=y_pos[14];z_ch<=z_pos[14];status<=D14;endelsestatus<=status;endelse if(status==D14)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[13];y_ch<=y_pos[13];z_ch<=z_pos[13];status<=D13;endelsestatus<=status;endelse if(status==D13)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[12];y_ch<=y_pos[12];z_ch<=z_pos[12];status<=D12;endelsestatus<=status;endelse if(status==D12)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[11];y_ch<=y_pos[11];z_ch<=z_pos[11];status<=D11;endelsestatus<=status;endelse if(status==D11)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[10];y_ch<=y_pos[10];z_ch<=z_pos[10];status<=D10;endelsestatus<=status;endelse if(status==D10)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[9];y_ch<=y_pos[9];z_ch<=z_pos[9];status<=D9;endelsestatus<=status;endelse if(status==D9)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[8];y_ch<=y_pos[8];z_ch<=z_pos[8];status<=D8;endelsestatus<=status;endelse if(status==D8)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[7];y_ch<=y_pos[7];z_ch<=z_pos[7];status<=D7;endelsestatus<=status;endelse if(status==D7)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[6];y_ch<=y_pos[6];z_ch<=z_pos[6];status<=D6;endelsestatus<=status;endelse if(status==D6)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[5];y_ch<=y_pos[5];z_ch<=z_pos[5];status<=D5;endelsestatus<=status;endelse if(status==D5)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[4];y_ch<=y_pos[4];z_ch<=z_pos[4];status<=D4;endelsestatus<=status;endelse if(status==D4)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[3];y_ch<=y_pos[3];z_ch<=z_pos[3];status<=D3;endelsestatus<=status;endelse if(status==D3)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[2];y_ch<=y_pos[2];z_ch<=z_pos[2];status<=D2;endelsestatus<=status;endelse if(status==D2)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[1];y_ch<=y_pos[1];z_ch<=z_pos[1];status<=D1;endelsestatus<=status;endelse if(status==D1)beginif(clk_2MHz_cnt==MaxCnt)beginx_ch<=x_pos[0];y_ch<=y_pos[0];z_ch<=z_pos[0];status<=D0;endelsestatus<=status;endelse if(status==D0)beginif(clk_2MHz_cnt==MaxCnt)beginsync<=1'd0;x_ch<=1'd0;y_ch<=1'd0;z_ch<=1'd0;status<=P;endelsestatus<=status;endelse if(status==P)beginif(clk_2MHz_cnt==MaxCnt)begintx_done<=1'd1;status<=Idle;endelsestatus<=status;end
endendmodule
仿真测试tb.v:
`timescale 1ns/1psmodule tb();//被测模块的输入信号必须在tb中必须是reg型
reg clk;
reg tx_init;
reg [15:0]x_pos;
reg [15:0]y_pos;
reg [15:0]z_pos;wire clk_2MHz_o;
wire sync_o;
wire x_ch_o;
wire y_ch_o;
wire z_ch_o;
wire tx_done_o;xy2_100 u1(.clk (clk ) ,.tx_init (tx_init ) , //当产生上升沿时,开始发数据.x_pos (x_pos ) ,.y_pos (y_pos ) ,.z_pos (z_pos ) ,.clk_2MHz_o (clk_2MHz_o ) ,//输出2MHz时钟.sync_o (sync_o ) ,.x_ch_o (x_ch_o ) ,.y_ch_o (y_ch_o ) ,.z_ch_o (z_ch_o ) ,.tx_done_o (tx_done_o )
);//产生时钟激励
initial clk = 1;
always #4 clk = ~clk;//输入激励
initial begin tx_init=0;x_pos=16'd43690;y_pos=16'd43690;z_pos=16'd43690;#10;tx_init = 1;
endendmodule
仿真波形: