⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parallel.v

📁 pci转local bus总线的应用
💻 V
字号:
/***Local Bus Interface*********************************************************/
//外接VSC7324

module parallel_interface (
	clock,reset_n,
	addr_in,data_in,data_out,ready_n,
	l_cmdo,abort_n,lt_framen,lt_ackn,lt_dxfrn,lt_tsr,
	pi_addr,pi_data,dir,oe_a,oe_d,
//zarlink
	cpu_cs_n,cpu_oe_n,cpu_we_n,
	cpu_ts_ale,cpu_ta_n,cpu_clk,
//cpld
    cpld_cs,cpld_wr,cpld_rd,
//rtc
	rtc_ad,rtc_cs_n,rtc_as,rtc_rw,rtc_ds,rtc_sqw,
	ot_cnt
	);

	input clock;
	input reset_n;	
//Back end Interface from "pci_top"
	input [21:0] addr_in;
	input [31:0] data_in;
	output [31:0] data_out;
	output ready_n;
	inout [3:0] l_cmdo;
	output abort_n;
	input lt_framen;
	input lt_ackn;
	input lt_dxfrn;
	input [11:0] lt_tsr;
//Parallel Interface
	output [21:0] pi_addr;
	inout [31:0] pi_data;
	output  dir;
	output  oe_a;
	output  oe_d;
//zarlink
    output cpu_cs_n;
	output cpu_oe_n;
	output cpu_we_n;
	output cpu_ts_ale;
	 input cpu_ta_n;
	output cpu_clk;
//cpld
    output cpld_cs;
    output cpld_wr;
    output cpld_rd;
//rtc
    inout [7:0] rtc_ad;
	output rtc_cs_n;
	output rtc_as;
	output rtc_rw;
	output rtc_ds;
	input rtc_sqw; 
	output [31:0] ot_cnt;//Over time error counter
	
//
//	output test_flag;//For test
//	input [7:0] ot_thr;//Overtime threshold (wait for pi_done_n)
	//output [31:0] ot_cnt;//Over time error counter
	reg [31:0] ot_cnt;
/******************************************************************************/
`define	BAR0 (lt_tsr[0] == 1'b1)	//Local
`define	BAR1 (lt_tsr[1] == 1'b1)	//zarlink
`define	BAR2 (lt_tsr[2] == 1'b1)	//RTC
`define	BAR3 (lt_tsr[3] == 1'b1)	//cpld
//`define	BAR4 (lt_tsr[4] == 1'b1)	//NA
//`define	BAR5 (lt_tsr[5] == 1'b1)	//NA
`define mem_read (l_cmdo == 4'b0110)
`define mem_write (l_cmdo == 4'b0111)
`define ot_thr 8'b00100000	//Overtime threshold (wait for pi_done_n)
/******************************************************************************/
    reg [31:0] pi_data_reg;
	reg [21:0] pi_addr;
//back 
	reg ready_n;
	reg abort_n;
//zar
	reg cpu_cs_n;
	reg cpu_oe_n;
	reg cpu_we_n;
	reg cpu_ts_ale;
//cpld
	reg cpld_cs;
    reg cpld_wr;
    reg cpld_rd;
//rtc
//	reg  rtc_ad;
	reg rtc_ad_ie;//input enable
	reg rtc_ad_oe;//output enable
	reg rtc_cs_n;
	reg rtc_as;
	reg rtc_rw;
	reg rtc_ds;
	reg [3:0] rtc_counter;
	reg [7:0] rtc_ad_out_reg;





/******************************************************************************/

	wire oe;//Enable pi_data output to IC
    assign cpu_clk = clock;
//	assign oe_a = 1'b0;
//  assign oe_d = 1'b0; 
	assign dir = ! ((`BAR1 || `BAR3) && `mem_read);//read 0;write 1
//	ascpldn oe = (`mem_write && (`BAR1 || `BAR2 || `BAR3 || `BAR4 || `BAR5));
	assign oe = (`mem_write && (`BAR1 ||`BAR2 ||`BAR3));
	assign pi_data = oe ? pi_data_reg : 32'hz;
	assign rtc_ad = (rtc_ad_oe) ? rtc_ad_out_reg : 8'hz;
//	assign data_out = (!oe) ? pi_data : 32'h0;
	assign data_out = ((rtc_ad_ie) ? {24'h0 , rtc_ad} : (!oe) ? pi_data : 32'h0);
/******************************************************************************/
//addr_in 锁存
always @(posedge clock or negedge reset_n)
	begin
	    if(!reset_n)
		    pi_addr <= 22'h0;
	    else 
		begin
		    if(!lt_framen && (`mem_write || `mem_read)  )
		    begin
			   pi_addr <= addr_in;
			end
/*		    else if(!lt_framen && (`mem_write || `mem_read) && `BAR2)
		    begin
		       		pi_addr[7:0]<=addr_in[7:0];
		    end  */
		         else ;
		end
	end
/******************************************************************************/
//data_in 锁存
always @(negedge lt_dxfrn or negedge reset_n)
	begin
	    if(!reset_n)
		    pi_data_reg <= 32'h0;
	    else 
	    begin
	    if(`mem_write )//&& `BAR1)
				pi_data_reg <= data_in;
	/*	     else if(`mem_write && `BAR3)
		    		pi_data_reg[7:0]<=data_in[7:0];
		 		  else ;*/
		else;
		end
	end

/******************************************************************************/
//State machine

	reg [7:0] ot_count;//Overtime counter

	reg [13:0] cstate;

	parameter [13:0]
		IDLE	    = 14'b00_0000_0000_0001,
		READ_ZAR	= 14'b00_0000_0000_0010,
		READ_ZAR_1  = 14'b00_0000_0000_0100,
		READ_ZAR_2  = 14'b00_0000_0000_1000,
		WRITE_ZAR   = 14'b00_0000_0001_0000,
		WRITE_ZAR_1 = 14'b00_0000_0010_0001,
		WRITE_ZAR_2 = 14'b00_0000_0100_0000,
		WRITE_ZAR_3 = 14'b00_0000_1000_0000,
		RTC_RD      = 14'b00_0001_0000_0000,
		RTC_WR      = 14'b00_0010_0000_0000,
		READ_CPLD   = 14'b00_0100_0000_0000,
		READ_CPLD_1 = 14'b00_1000_0000_0000,
		WRITE_CPLD  = 14'b01_0000_0000_0000,
		WRITE_CPLD_1= 14'b10_0000_0000_0000;

/******************************************************************************/
always @(posedge clock or negedge reset_n)
	begin
	    if(!reset_n)
		begin
		    ready_n <= 1'b1;
		    abort_n <=1'b1;
		//zar
		    cpu_we_n <= 1'b1;          
		    cpu_oe_n <= 1'b1;          
		    cpu_cs_n <= 1'b1;          
		    cpu_ts_ale <= 1'b0; 
		//cpld
		    cpld_cs <= 1'b1;
    		cpld_wr <= 1'b1;
    		cpld_rd <= 1'b1;
		//rtc
		    rtc_ad_ie <= 1'b0;
		    rtc_ad_oe <= 1'b0;
		    rtc_cs_n <= 1'b1;
		    rtc_as <= 1'b0;
		    rtc_rw <= 1'b1;
		    rtc_ds <= 1'b1;  
		    rtc_counter <= 8'h0;
		    rtc_ad_out_reg <= 8'h0;
		    ot_count <= 8'b0;
		    ot_cnt <= 32'b0;
		 //   test_flag <= 1'b0;
		    cstate <= IDLE;
		end
	    else
		begin
		    case(cstate)

			IDLE:
			    begin
				rtc_counter <= 8'h0;
				rtc_ds <= 1'b1;
				rtc_rw <= 1'b1;
				rtc_cs_n <= 1'b1;
				rtc_ad_ie <= 1'b0;
				rtc_ad_oe <= 1'b0; 
				ot_count <= 8'b0;
				if(!lt_framen && `mem_read && (`BAR1))  //zar read
				    begin
					cpu_we_n <= 1'b1;   //开始读操作
					cpu_oe_n <= 1'b0;  //使能zl的读信号(read=0)
					cpu_cs_n <= 1'b0;  //片选有效
					cpu_ts_ale <= 1'b1; //地址锁存有效
					cstate <= READ_ZAR; //此时frame信号有效
				    end
				else if(!lt_framen && `mem_write && (`BAR1)) //zar write
				    begin
					ready_n <= 1'b0;  //接收端已经准好了接收数据
					cpu_oe_n <= 1'b1;
					cpu_we_n <= 1'b0;
					cpu_cs_n <= 1'b0;  //地址片选有效
					cpu_ts_ale <= 1'b1; //地址锁存有效
					cstate <= WRITE_ZAR;//CS 触发
				    end
//				else if(!lt_framen && `mem_write && (1'b0))
//				    begin
//					ready_n <= 1'b0;
//					cstate <= WRITE2;//WR 触发
//				    end
				else if(!lt_framen && `mem_read && (`BAR2))  //rtc read
				    begin
					//ready_n <= 1'b0;
					cstate <= RTC_RD;//RTC read
				    end
				else if(!lt_framen && `mem_write && (`BAR2)) //rtc write
				    begin
					ready_n <= 1'b0;
					cstate <= RTC_WR;//RTC write
				    end  
				else if(!lt_framen && `mem_read && `BAR3)  //cpld read
					begin
					cpld_cs <= 1'b0;
					cpld_rd <= 1'b0;
					cpld_wr <= 1'b1;
//					ready_n <= 1'b0;
					cstate <= READ_CPLD;
					end
				else if(!lt_framen && `mem_write && `BAR3)  //cpld write
					begin
					ready_n <= 1'b0;
					cpld_cs <= 1'b0;
					cpld_wr <= 1'b0;
					cpld_rd <= 1'b1;
					cstate <= WRITE_CPLD;
					end
				else
				    begin
					ready_n <= 1'b1;
					abort_n <=1'b1;
					//zar
		  			cpu_we_n <= 1'b1;          
		    		cpu_oe_n <= 1'b1;          
		    		cpu_cs_n <= 1'b1;          
		    		cpu_ts_ale <= 1'b0; 
					//cpld
		    		cpld_cs <= 1'b1;
    				cpld_wr <= 1'b1;
    				cpld_rd <= 1'b1;
					//rtc
				    rtc_ad_ie <= 1'b0;
		    		rtc_ad_oe <= 1'b0;
		    		rtc_cs_n <= 1'b1;
		    		rtc_as <= 1'b0;
		    		rtc_rw <= 1'b1;
		    		rtc_ds <= 1'b1; 
		    		rtc_counter <= 8'h0;
		    		rtc_ad_out_reg <= 8'h0;
					cstate <= IDLE;
				    end
			    end

			READ_ZAR:
			     begin
				cpu_ts_ale <= 1'b1;
				cpu_cs_n <= 1'b0;
				cpu_oe_n <= 1'b0;
				cstate <= READ_ZAR_1;
			    end
			
			READ_ZAR_1:
			    begin
				cpu_ts_ale <= 1'b0;
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					ready_n <= 1'b1;
					abort_n <= 1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					cstate <= IDLE;
				    end
				else if(!cpu_ta_n)   //本地数据准好了,可以读入,等待本地总线准备好!
				    begin
					ready_n <= 1'b0;  //local bus 准备好
					ot_count <= 8'b0;
					cstate <= READ_ZAR_2;
				    end
				else
				    cstate <= READ_ZAR_1;
			    end
			
			READ_ZAR_2:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					abort_n <= 1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
				else if(!lt_framen)  //只有等frame信号无效时,本地数据才真正的传输到PCI总线上去。
				    cstate <= READ_ZAR_2; //等待PCI总线把数据读完,以便进行下一此数据的读写。
				else
				    begin
					cpu_oe_n <= 1'b1;
					cpu_cs_n <= 1'b1;
					ot_count <= 8'b0;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
			    end

			WRITE_ZAR:
			   begin
			    cpu_ts_ale <= 1'b1;
			   	cpu_cs_n <= 1'b0;
			   	cpu_we_n <= 1'b0;   //本地能有效
			//	cpu_ts_ale <= 1'b1;  //地址锁存到本地端
				cstate <= WRITE_ZAR_1;
			   end

			WRITE_ZAR_1:
			    begin
				cpu_ts_ale <= 1'b0;
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					ready_n <= 1'b1;
					abort_n <=1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					cstate <= IDLE;
				    end
				else if(!lt_dxfrn) //等数据到local端,到了之后就交给本地端进行时序控制!
				    begin
					ready_n <= 1'b1; //数据到了local端,那么不使能local端。
					ot_count <= 8'b0; 
					cstate <= WRITE_ZAR_2;
				    end
				else
				    begin
					cstate <= WRITE_ZAR_1;
				    end
			    end
			    
			WRITE_ZAR_2:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					abort_n <=1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
				else if(!cpu_ta_n)   //数据已经到了local端,等待本地端有效接收
				    begin
				//	cpu_we_n <= 1'b1; //本地接收到数据之后,就禁止再写入数据。
					ot_count <= 8'b0;
					cstate <= WRITE_ZAR_3;
				    end
				else
				    begin
					cstate <= WRITE_ZAR_2;
				    end
			    end

			WRITE_ZAR_3: //数据已经处理完了,恢复到空闲状态!
			    begin
			    cpu_we_n <= 1'b1;
				cpu_cs_n <= 1'b1;
			//	ready_n <= 1'b1;
				cstate <= IDLE;
			    end

/*			WRITE2:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == ot_thr)
				    begin
					ready_n <= 1'b1;
					abort_n <=1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					cstate <= IDLE;
				    end
				else if(!lt_dxfrn)
				    begin
					pi_wr <= 1'b0;
					pi_cs_n[5] <= 1'b0;
					ready_n <= 1'b1;
					ot_count <= 8'b0;
					cstate <= W2_WAIT;
				    end
				else
				    cstate <= WRITE2;
			    end
			    
			W2_WAIT:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == ot_thr)
				    begin
					abort_n <=1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					cstate <= IDLE;
				    end
				else if(!pi_done_n_wire)
				    begin
					pi_wr <= 1'b1;
					pi_cs_n[5] <= 1'b1; 
					ot_count <= 8'b0;
					cstate <= IDLE;
				    end
				else
				    cstate <= W2_WAIT;
			    end
          */
			RTC_RD:
			    begin
				rtc_counter <= rtc_counter + 1'b1;
				if(rtc_counter == 1) begin
					rtc_ad_out_reg <= addr_in[7:0];
					rtc_as <= 1'b1;
					rtc_cs_n <= 1'b0;
					rtc_ad_oe <= 1'b1; end
				else if(rtc_counter == 3) begin
					rtc_as <= 1'b0; end
				else if(rtc_counter == 6) begin
					rtc_ds <= 1'b0;
					rtc_ad_oe <= 1'b0; end
				else if(rtc_counter == 9) begin
					ready_n <= 1'b0;
					rtc_ad_ie <= 1'b1; end
				else if(rtc_counter == 11) begin
					ready_n <= 1'b1;
					rtc_ad_ie <= 1'b0;
					rtc_ds <= 1'b1; end
				else if(rtc_counter == 12) begin
					rtc_cs_n <= 1'b1;
					cstate <= IDLE; end
				else begin
					cstate <= RTC_RD; end
			    end

			RTC_WR:
			    begin
				rtc_counter <= rtc_counter + 1'b1;
				if(rtc_counter == 1) begin
					rtc_ad_out_reg <= addr_in[7:0];
					rtc_as <= 1'b1;
					rtc_cs_n <= 1'b0;
					rtc_ad_oe <= 1'b1; end
				else if(rtc_counter == 3) begin
					ready_n <= 1'b1;
					rtc_as <= 1'b0; end
				else if(rtc_counter == 6) begin
					rtc_ad_out_reg <= pi_data_reg[7:0];
					rtc_rw <= 1'b0; end
				else if(rtc_counter == 11) begin
					rtc_cs_n <= 1'b1;
					rtc_rw <= 1'b1; end
				else if(rtc_counter == 12) begin
					rtc_ad_out_reg <= 8'h0;
					rtc_ad_oe <= 1'b0;
					cstate <= IDLE; end
				else begin
					cstate <= RTC_WR; end
			    end
		
			READ_CPLD:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == 8'b00000010)  //等待90nS
				    begin
					ot_count <= 8'b0;
					ready_n <= 1'b0;
					cstate <= READ_CPLD_1;
				    end
				else
				    cstate <= READ_CPLD;
			    end
			
			READ_CPLD_1:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					abort_n <= 1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
				else if(!lt_framen)
				    cstate <= READ_CPLD_1;
				else
				    begin
					cpld_cs <= 1'b1;
					cpld_wr <= 1'b1;
					cpld_rd <= 1'b1;
					ot_count <= 8'b0;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
			    end

			WRITE_CPLD:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == `ot_thr)
				    begin
					ready_n <= 1'b1;
					abort_n <=1'b0;
					ot_count <= 8'b0;
					ot_cnt <= ot_cnt + 1;
					cstate <= IDLE;
				    end
				else if(!lt_dxfrn)
				    begin
					cpld_cs <= 1'b1;
					ready_n <= 1'b1;
					ot_count <= 8'b0;
					cstate <= WRITE_CPLD_1;
				    end
				else
				    cstate <= WRITE_CPLD;
			    end
			    
			WRITE_CPLD_1:
			    begin
				ot_count <= ot_count + 1 ;
				if(ot_count == 8'b00000011)
				    begin
					ot_count <= 8'b0;
					cpld_cs <= 1'b1;
					cpld_wr <= 1'b1;
					cpld_rd <= 1'b1;
					ready_n <= 1'b1;
					cstate <= IDLE;
				    end
				else
				    cstate <= WRITE_CPLD_1;
			    end
			default: cstate <= IDLE;
		    endcase
		end
	end

/******************************************************************************/
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -