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

📄 maincontrol.v

📁 高速AD采集卡应用程序及SDRAM控制器
💻 V
字号:
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:    17:18:45 01/18/06
// Design Name:    
// Module Name:    maincontrol
// Project Name:   
// Target Device:  
// Tool versions:  
// Description:
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

//注意:100M猝发读写:的确切含义是以100M采样,以更高的频率(系统的工作时钟,暂定为105MHz)读写SDRAM,以50M的速度从pci读取数据
//在FPGA本地侧的控制逻辑(从PCI—FIFO读取数据的逻辑)一定要与PCI9054的50M时钟一致





module maincontrol (clk,clk50m,doing_precharge,rd_count,doing_refresh,lwr,blast,ads,sd_data_out,sd_rst,addr,do_write,do_read,do_write_ack,do_read_ack,ainit,FIFO_ad_rd,FIFO_ad_wr,pci_data
							,sddataout_reg1);

//-------------------------IO

input clk;
input clk50m;
input doing_precharge;
input doing_refresh;

input [31:0] sd_data_out;

input [1:0]rd_count;


input lwr;
input blast;
input ads;
input do_read_ack;
input do_write_ack;


output sd_rst;
output [12:0] addr;
output do_write;
output do_read;

output ainit;

output FIFO_ad_rd;
output FIFO_ad_wr;
output sddataout_reg1;


inout [31:0] pci_data;

//---------------------------REG
reg sd_rst;
reg [12:0] addr;
reg do_write;
reg do_read;

reg ainit;
reg FIFO_ad_wr;
reg [2:0] rst_counter;




reg [7:0] read_counter;
reg [7:0] write_counter;

reg [31:0] reg_data;
reg [31:0] pci_out_reg;


reg	mem_write_ena;
reg 	[31:0] sddataout_reg1;

reg read_ack_reg1;

reg [3:0] next_state;
//---------------------------------------wire  用于连接FIFO core和逻辑

wire [1:0] rd_count;
wire FIFO_ad_rd;
wire [31:0] mem_data_out;

//---------------------------------------parameter
   parameter   reset=4'd0,
					IDLE=4'd1,
               arbitrate =4'd2, 
					send_write_cmd=4'd3,
               write_wait=4'd4,
					write_burst=4'd5,
					
					precharge_wait=4'd6,
					send_read_cmd=4'd7,
					read_wait=4'd8,
					burst_read=4'd9;
						

//-------------------------------------------------------------------FIFO_ad_rd
	assign FIFO_ad_rd = do_write_ack;
//--------------------------------------------------------------------

always@(posedge clk)
begin
	if(!sd_rst)
		begin
			read_ack_reg1<=1'b0;
	
		end
		else
			begin
				read_ack_reg1<=do_read_ack;
			
			end
end


//-----------------------------------------------------------------state machine
//各个状态的操作:

always @(posedge clk)

begin
	case (next_state)

		reset:
			begin
				sd_rst<=1'b0;
				addr<=13'd0;
				do_write<=1'b0;
				do_read<=1'b0;
				ainit<=1'b1;
			   
				write_counter<=9'd0;
			
				FIFO_ad_wr<=1'b0;
				mem_write_ena<=1'b0; 	//停止向pcimem写数据	
				
				
			
				
				

			
 				if(rst_counter==3'd7)			////将reset状态延长7个周期

					begin
						rst_counter<=3'd0;
						next_state<=IDLE;
					end
				else
					begin
						rst_counter<=rst_counter+1;
						next_state<=reset;
					end 
                                
			end
	
//----------------------------------------------------------------------------------
		IDLE:
			begin
				rst_counter<=3'd0;
				sd_rst<=1'b1;
				ainit<=1'b0;				
            do_read<=1'b0;
				do_write<=1'b0;
		
			write_counter<=9'd0;			
				
				FIFO_ad_wr<=1'b0;//停止向ad FIFO写数据 

				

				if(lwr&(!blast))					//每当pci写入数据或命令时,跳转至“判断”状态
					next_state<=arbitrate;
				else next_state<=IDLE;
				
			end
 //------------------------------------------------------------------------------------------------
		arbitrate:
	
		begin
			if(reg_data==32'd0)				 //reset命令	,跳转之reset状态
				begin
					sd_rst<=1'b0;
					next_state<=reset;		
				end
   
			else if(reg_data==32'd2147479278)	  //发出读行命令,跳转至send_read_cmd状态
	
			  next_state<=send_read_cmd;
					
			else	if(reg_data==32'd47)				 //发出写命令,跳转至send _write_cmd状态
				next_state<=send_write_cmd; 			
			else next_state<=IDLE;		
		end
//-----------------------------------------------------------------------------------------
		send_write_cmd:
				begin	

					FIFO_ad_wr<=1'b1;   //开始向FIFO写数据
					sd_rst<=1'b1;
					if(doing_refresh)       //如果正在进行refresh,等结束后再写
						begin
						
							
							do_write<=1'b0;   //停止向SDRAM写数据
						
							next_state<=send_write_cmd;
						end
					else
						begin		

					 
							if(rd_count>=2'b01)   
								begin
								

									do_write<=1'b1;	 								

									next_state<=write_wait;
								end
							else                   
													
								begin
  								
									do_write<=1'b0;     
								

									next_state<=send_write_cmd;					
						
								end

					
			
					
						end
			end
//---------------------------------------------------------------------------------------
		write_wait:	  //等待写入开始
			begin
			
				FIFO_ad_wr<=1'b1;//将AD数据写入FIFO
				sd_rst<=1'b1;
				if(do_write_ack) //收到写应答,表示下个周期数据开始有效的写入SDRAM
					begin
						do_write	<=1'b0;
						next_state<=write_burst;  //进入写猝发
					end
				else
					begin
						do_write<=1'b1;
						next_state<=write_wait;
					end
				
			end
//--------------------------------------------------------------------------------------
	

 	  write_burst:	//等待写猝发结束
	  		begin			  				
				
					FIFO_ad_wr<=1'b1;
					sd_rst<=1'b1;
				if(do_write_ack)

					begin
					
						
						next_state<=write_burst;
					end
				else //猝发写入完成
					begin
				
						addr<=addr+1;		//进行过precharge之后,行地址加1
						
					
						next_state<=precharge_wait;
		
					end
				
			end
//----------------------------------------------------------------------------------------



//--------------------------------------------------------------------------------
	precharge_wait:		 //等待precharge结束
		begin	 
				sd_rst<=1'b1;				 			

				if(doing_precharge)              //  在sdram控制模块中,每写完一行并precharge后,
					begin
							FIFO_ad_wr<=1'b1;
						next_state<=precharge_wait;       //等待auto refresh完成
					end
				else 
					begin  //precharge结束之后
						if(addr==13'b1111111111111) //行地址和BANK地址加满
							begin
								addr<=13'd0;			//ba和行地址清零					
									//	FIFO_ad_rd<=1'b0;//停止读AD FIFO
								FIFO_ad_wr<=1'b0;//停止向AD FIFO写数据

								next_state<=IDLE;
							end
						else 
							begin
								FIFO_ad_wr<=1'b1;
								next_state<=send_write_cmd;
							end		  //没有写完2M的数据,再接着写
					  //在send_write_cmd状态中等待refresh结束
					end

		end  
//---------------------------------------------------------------------------------
		send_read_cmd:						  //发出读命令
			begin
			sd_rst<=1'b1;
			do_write<=1'b0;				//添加,保证稳定
				if(doing_refresh)       //如果正在进行refresh,等结束后再读

					begin
						do_read<=1'b0;  //停止读SDRAM 
						
						next_state<=send_read_cmd;	 						
					end
				else
					begin
						do_read<=1'b1;
					
					next_state<=read_wait;
					end
				
			end
//--------------------------------------------------------------------------------
	
	//调试屏蔽	  
	
		read_wait:						//		等待读应答信号
			begin
			sd_rst<=1'b1;
			do_write<=1'b0;		  //添加,保证稳定
			//	if(do_read_ack)   //当收到do_read_ack后表示下一个周期数据有效,开始接受数据
			if(read_ack_reg1)   //当收到read_ack_reg1后表示下一个周期数据有效,开始接受数据		
						begin
						
							do_read<=1'b0;	
							//mem[0]<= sd_data_out;//
							mem_write_ena<=1'b1;	  //开始向pcimem写数据
								 							
							next_state<=burst_read;
						end		 
					else next_state<=read_wait;

				
			end
//----------------------------------------------------------------------------------  		
   	burst_read:							  //读猝发,将SDRAM的数据以行猝发的方式读到FPGA中
   			begin		
		
					 sd_rst<=1'b1;
					 do_write<=1'b0;		  
				//	if(mem_addr==9'd256)			 //到256后清零,有效mem地址是0-255,共256个
					if(write_counter==8'd255)
			
						begin
					
						write_counter<=8'd0;	
					
						mem_write_ena<=1'b0; 	//停止向pcimem写数据						
							addr<=addr+1;          //读完一行后,行地址加1
							next_state<=IDLE;			//写完了一行(256列),进入IDLE状态
						end
					 else 
						begin
					
							mem_write_ena<=1'b1; 	//开始向pcimem写数据	
						write_counter<=write_counter+1;
							next_state<=	burst_read;
						end

					

				
			end		 
										  
//------------------------------------------------------------------------------
		default:
			next_state<=IDLE;

	endcase


end

//--------------------------------------------------------------read pci_mem

always@(posedge clk50m or negedge sd_rst)  //与pci侧的50M时钟同步

	begin
	


			if(!sd_rst)		
				begin
				
					read_counter<=8'd0;
					pci_out_reg<=32'd0;
			
				end
			

			else if((!lwr)&(!ads))    //当pci发出读命令时
				
						begin
      				
						if(read_counter==8'd255)	//只有发出读命令时才改变地址,否则地址不变
							 read_counter<=8'd0;	
						else
							begin
								read_counter<=read_counter+1;
								pci_out_reg<=mem_data_out;
							end
						end
		


	end


//-----------------------------------------------------------------------------双向总线pci_data的控制


 //pci端双向总线的输入,将输入的命令存储在reg_data

always@(posedge clk50m or negedge sd_rst)   //与pci侧的50M时钟同步

	begin
		if(!sd_rst)					 
			reg_data<=32'd0;
		else if(lwr&(!blast))     //每当pci写入命令时
		   reg_data<=pci_data;	//	将输入命令寄存
	end																		 

//-------------------------------------------------------------------------
//pci端双向总线的输出
assign pci_data = ((!lwr)&(!ads))? 	pci_out_reg: 32'hzzzzzzzz;//当输出使能时,将pci_mem的数据输出,否则为高阻

//-------------------------------------------------------------------
//using pcimem
 pcimem mypcimem(
	.addra(write_counter[7:0]),
	.addrb(read_counter[7:0]),
	.clka(clk),
	.clkb(clk50m),
	.dina(sd_data_out),

	
	.doutb(mem_data_out),
	.wea(mem_write_ena));


	always@(posedge clk or negedge sd_rst)	 //将从sdram中读回的数据用寄存器存储,
															
	begin
		if(!sd_rst)
		 begin
			sddataout_reg1<=32'd0;
			
		  end
		else
			begin
				sddataout_reg1<=sd_data_out;
				
			end
	end 

endmodule


⌨️ 快捷键说明

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