FPGA实现IO口检测程序

  • A口和B口通过一个电阻相连,都是双向IO口,通过上拉电阻连接VDD。FPGA芯片引脚分别与A,B口相接。

A,B口可能存在的问题

某一个口接地
A1,B1口开路
A1,A2短路
B1,B2短路
  • IO_test.v主程序模块
module io_test(
	inout [29:0] JH2_A,			//JH1 A口   30个A口    A_register表示
//////////////////////////////////////
	inout [29:0] JH2_B,			//JH1 B口      30个B口  B_register表示	
	
	input  wire clk,				//50mhz
	input  wire rst_n,
	input  wire	clr,
	output wire zz,					//为了实验激励信号而存在
	output reg [30:0] A_out_chk,
	output reg [59:0] error_out,error_out1,error_out0,
	output reg process,
	output reg  [59:0] error_out_fifo			//上电检测的错误加上不同A_out输出情况反馈回的错误的集合
);
	reg [30:0] A_out;
	//reg [59:0] error_out,error_out1,error_out0;	
	/*error_out0         为扫描上电时得出的(接地端口)错误信号;
	  error_out1         为A口一次输出得出的(A、B开路,B1、B2短路,A1、A2短路)错误信号。*/   		
	//reg process;				//if 0,上电检测模式. if 1,短路检测模式. 
	reg z ;		//三态门选通信号
	assign zz = ~z;
//-----------------------------------------------------------------------------------------
//双向IO口的使用
	assign  JH2_A = (!z)?A_out[29:0]:30'bz;	
//-----------------------------------------------------------------------------------------
///////////////////////////////////////一周期扫描的状态机 
	always @(posedge clk or negedge rst_n)
	begin
	// 复位
		if(rst_n==0) begin
			process    <= 0;
			error_out1 <= 60'h0;			
			error_out0 <= 60'h0;
			error_out <= 60'h0;
			z 		   <= 1;
			A_out     <= 31'bzzz_zzzz_zzzz_zzzz_zzzz_zzzz_zzzz_zzz0;
			A_out_chk     <= 31'b111_1111_1111_1111_1111_1111_1111_1110;
		end
	//上电检测模式
		else if(process == 0) begin		
			error_out0[59:30] <= ~JH2_A;		//A口在高位,B口在低位
			error_out0[29:0]  <= ~JH2_B;
			error_out1 <= 60'h0;			
			process <= 1;
			z <= 0;
		end
		
	//短路、开路检测模式	
		else begin 
			if(A_out_chk[30] == 0) begin  //一周期结束,
				process   <= 0;
				z <= 1;
				A_out_chk <= {A_out_chk[29:0],A_out_chk[30]};
				A_out <= {A_out[29:0],A_out[30]};
				error_out <= error_out1|error_out0;
			end
			else begin	
				//对A口输出一次,得出端口错误信息
				if(z==0) begin	//输出
					z <= 1;	
					error_out1 <= error_out1;
					A_out <= A_out;
					A_out_chk <= A_out_chk;
					
				end
				else begin		//比较
					error_out1 <= error_out1 | ( ( {A_out_chk[29:0],A_out_chk[29:0]}&(~error_out0) ) ^ {JH2_A,JH2_B} );
					A_out <= {A_out[29:0],A_out[30]};
					A_out_chk <= {A_out_chk[29:0],A_out_chk[30]};
					z <= 0;
				end
			end
		end
	end
//-----------------------------------------------------------------
//--error_out_fifo为n个周期error_out的累加,除非clr或rst_n有效
	always @(posedge clk or negedge rst_n)		
	begin
		if(rst_n==0) 
			error_out_fifo <= 60'b0; 
		else if(clr==1) 
			error_out_fifo <= 60'b0; 
		else
			error_out_fifo <= error_out_fifo|error_out;
	end
endmodule
  • testbench模块
`timescale 1ns / 1ps
`define halfperiod 2
////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   13:53:01 04/02/2020
// Design Name:   io_test
// Module Name:   D:/lsc/io_test/io_test_tb.v
// Project Name:  io_test
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: io_test
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module io_test_tb;

	// Inputs
	reg clk;
	reg rst_n;
	reg clr;
	wire [59:0] error_out,error_out1,error_out0;
	wire [30:0] A_out_chk;	
	// Outputs
	wire [59:0] error_out_fifo;
	wire process;

	// Bidirs
	wire [29:0] JH2_A;
	wire [29:0] JH2_B;
	wire zz;
	// Instantiate the Unit Under Test (UUT)
	io_test uut (
		.JH2_A(JH2_A), 
		.JH2_B(JH2_B), 
		.clk(clk), 
		.rst_n(rst_n), 
		.clr(clr), 
		.zz(zz),
		.A_out_chk(A_out_chk),
		.error_out(error_out),
		.error_out1(error_out1),
		.error_out0(error_out0),
		.process(process),
		.error_out_fifo(error_out_fifo)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		clr = 0;
		rst_n = 0;
		// Wait 100 ns for global rst_n to finish
		#20;
        rst_n = 1;  
		// Add stimulus here
	    #(`halfperiod*8000) $stop;
	end
	
	always #(`halfperiod) clk <= ~clk;
   // assign JH2_B = JH2_A; 
	reg [29:0] A_OUT_reg= 30'h3FFF_FFEF;
	//reg [29:0] A_OUT_reg= 30'h3FFF_FFFF;
	integer i=0;
	always@(posedge clk) begin
		if(zz==1) begin
			for(i=0;i<30;i = i + 1) begin
				if(JH2_A[i]==0||i==4)
					A_OUT_reg[i] <= 0;
				else 
					A_OUT_reg[i] <= 1;
			end
		end
		else begin
			A_OUT_reg <= A_OUT_reg;
			i <= 0;			//i要置零,但这不是最佳选择把?
		end
	end
	assign  JH2_A = (!zz)?A_OUT_reg:30'bz;
	//assign  JH2_B = JH2_A;
	assign JH2_B[1:0] = JH2_A[1:0];
	assign JH2_B[2] = 1;
	assign JH2_B[29:3] = JH2_A[29:3];
	
endmodule
  • 仿真波形

你可能感兴趣的:(FPGA)