XY2-100的Verilog实现

xy2_100.v

Matlab 复制代码
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)
begin
	if(generate_clk_2MHz_cnt==XY2_100_2MHz_Reverse_Cnt)
	begin
		generate_clk_2MHz_cnt<=6'd0;
		clk_2MHz<=~clk_2MHz;
	end
	else
		generate_clk_2MHz_cnt<=generate_clk_2MHz_cnt + 6'd1;
	
	if(clk_2MHz_cnt==MaxCnt)
		clk_2MHz_cnt<=7'd0;
	else
		clk_2MHz_cnt<=clk_2MHz_cnt+7'd1;

	tx_init1<=tx_init;
	tx_init2<=tx_init1;
end

localparam 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)
begin
	if(status==Idle)
	begin
		tx_done<=1'd0;
		if(start_transaction==1'd1)
			status<=Wait_First_2MHz_Posedge;
		else
			status<=status;
	end

	else if(status==Wait_First_2MHz_Posedge)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			sync<=1'd1;
			x_ch<=1'd0;
			y_ch<=1'd0;
			z_ch<=1'd0;
			status<=C2;
		end
		else
			status<=status;
	end

	else if(status==C2)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=1'd0;
			y_ch<=1'd0;
			z_ch<=1'd0;
			status<=C1;
		end
		else
			status<=status;
	end
	
	else if(status==C1)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=1'd1;
			y_ch<=1'd1;
			z_ch<=1'd1;
			status<=C0;
		end
		else
			status<=status;
	end

	else if(status==C0)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[15];
			y_ch<=y_pos[15];
			z_ch<=z_pos[15];
			status<=D15;
		end
		else
			status<=status;
	end

	else if(status==D15)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[14];
			y_ch<=y_pos[14];
			z_ch<=z_pos[14];
			status<=D14;
		end
		else
			status<=status;
	end

	else if(status==D14)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[13];
			y_ch<=y_pos[13];
			z_ch<=z_pos[13];
			status<=D13;
		end
		else
			status<=status;
	end

	else if(status==D13)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[12];
			y_ch<=y_pos[12];
			z_ch<=z_pos[12];
			status<=D12;
		end
		else
			status<=status;
	end

	else if(status==D12)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[11];
			y_ch<=y_pos[11];
			z_ch<=z_pos[11];
			status<=D11;
		end
		else
			status<=status;
	end

	else if(status==D11)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[10];
			y_ch<=y_pos[10];
			z_ch<=z_pos[10];
			status<=D10;
		end
		else
			status<=status;
	end

	else if(status==D10)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[9];
			y_ch<=y_pos[9];
			z_ch<=z_pos[9];
			status<=D9;
		end
		else
			status<=status;
	end

	else if(status==D9)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[8];
			y_ch<=y_pos[8];
			z_ch<=z_pos[8];
			status<=D8;
		end
		else
			status<=status;
	end

	else if(status==D8)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[7];
			y_ch<=y_pos[7];
			z_ch<=z_pos[7];
			status<=D7;
		end
		else
			status<=status;
	end

	else if(status==D7)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[6];
			y_ch<=y_pos[6];
			z_ch<=z_pos[6];
			status<=D6;
		end
		else
			status<=status;
	end

	else if(status==D6)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[5];
			y_ch<=y_pos[5];
			z_ch<=z_pos[5];
			status<=D5;
		end
		else
			status<=status;
	end

	else if(status==D5)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[4];
			y_ch<=y_pos[4];
			z_ch<=z_pos[4];
			status<=D4;
		end
		else
			status<=status;
	end

	else if(status==D4)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[3];
			y_ch<=y_pos[3];
			z_ch<=z_pos[3];
			status<=D3;
		end
		else
			status<=status;
	end

	else if(status==D3)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[2];
			y_ch<=y_pos[2];
			z_ch<=z_pos[2];
			status<=D2;
		end
		else
			status<=status;
	end

	else if(status==D2)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[1];
			y_ch<=y_pos[1];
			z_ch<=z_pos[1];
			status<=D1;
		end
		else
			status<=status;
	end

	else if(status==D1)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			x_ch<=x_pos[0];
			y_ch<=y_pos[0];
			z_ch<=z_pos[0];
			status<=D0;
		end
		else
			status<=status;
	end

	else if(status==D0)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			sync<=1'd0;
			x_ch<=1'd0;
			y_ch<=1'd0;
			z_ch<=1'd0;
			status<=P;
		end
		else
			status<=status;
	end

	else if(status==P)
	begin
		if(clk_2MHz_cnt==MaxCnt)
		begin
			tx_done<=1'd1;
			status<=Idle;
		end
		else
			status<=status;
	end
end

endmodule

仿真测试tb.v:

Matlab 复制代码
`timescale 1ns/1ps
 
module 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;
end

endmodule 

仿真波形:

相关推荐
szxinmai主板定制专家2 小时前
国产RK3568+FPGA以 ‌“实时控制+高精度采集+灵活扩展”‌ 为核心的解决方案
大数据·运维·网络·人工智能·fpga开发·机器人
FPGA_ADDA3 小时前
基于FPGA 和DSP 的高性能6U VPX 采集处理板
fpga开发·dsp·6u vpx·8通道采集
FakeOccupational6 小时前
fpga系列 HDL:跨时钟域同步 脉冲展宽同步 Pulse Synchronization
fpga开发
丶七年先生6 小时前
牛客 verilog入门 VIP
fpga开发
hahaha60169 小时前
ARINC818协议(六)
网络·fpga开发
深圳信迈科技DSP+ARM+FPGA10 小时前
基于ARM+FPGA+DSP的储能协调控制器解决方案,支持国产化
arm开发·fpga开发·信号处理
承接电子控制相关项目13 小时前
单片机与FPGA的核心差异、优缺点、编程差异、典型应用场景、选型等对比分析
单片机·嵌入式硬件·fpga开发
XINVRY-FPGA15 小时前
XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
c++·嵌入式硬件·阿里云·fpga开发·云计算·硬件工程·fpga
kanhao1001 天前
为什么FPGA中一般不使用浮点数进行计算?
fpga开发
9527华安1 天前
国产紫光同创FPGA实现SDI视频编解码+图像缩放,基于HSSTHP高速接口,提供2套工程源码和技术支持
fpga开发·视频编解码·图像缩放·紫光同创·sdi·高速接口·hssthp