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

📄 ms_core.v

📁 I2C总线的verilog语言实现
💻 V
📖 第 1 页 / 共 2 页
字号:
		//if(arbitration_lost)					//if arbitration lost then go to idle state releasing buses.remove this because its a 			//scl_main_state<=scl_main_idle;		//software problem if even after arb_lost it is giving wr/rd then it has to go to respective state.		if(detect_stop)		begin						//Go to idle state if there is stop command			scl_main_state<=scl_main_idle;			sm_stop_sig<=1'b0;		end		else if(detect_start)		begin			scl_main_state<=scl_address_shift;			sm_stop_sig<=1'b0;		end		//else if(!sda_in)							//If ack has been received then,check for slave/master			else if(master_slave)			begin				//if master then set the direction for master to either transmit 			   if(!master_rw)				//or receive the data.			   	scl_main_state<=scl_rx_data;			   else				scl_main_state<=scl_tx_data;	//Ravi: if no detect_stop then check if master send to state depending upon 			end									//tx/rx bit of control register.						else			begin						//If slave then check if received address has matched			   //if(addr_match)			   //begin  					//if address matches then set the direction of communication based 			      if(add_reg[0])				//last bit of shift register of address cycle.				   scl_main_state<=scl_tx_data;			      else				    scl_main_state<=scl_rx_data;			 end			   //else				//scl_main_state<=scl_main_idle;			//end				//else		//begin		//	scl_main_state<=scl_main_idle;				//If no ack received go to idle state.			//if(master_slave)		//	sm_stop_sig<=1'b1;		//end	scl_rx_data:		if(bit_cnt == 8'b0000_0111)			scl_main_state<=scl_send_ack;		else if(detect_stop)		begin			scl_main_state<=scl_main_idle;			sm_stop_sig<=1'b0;		end		else if(detect_start)		begin			scl_main_state<=scl_address_shift;			sm_stop_sig<=1'b0;		end						scl_tx_data:		if(bit_cnt == 8'b0000_0111)			scl_main_state<=scl_wait_ack;		else if(detect_stop)		begin			scl_main_state<=scl_main_idle;			sm_stop_sig<=1'b0;		end		else if(detect_start)		begin			scl_main_state<=scl_address_shift;			sm_stop_sig<=1'b0;		end	scl_send_ack:		if(detect_stop)		begin			scl_main_state<=scl_main_idle;			sm_stop_sig<=1'b0;		end		else			scl_main_state<=scl_rx_data;	scl_wait_ack:								//Ravi: Even in this state machine will goto Tx state,if no ack or arb_lost has occur  		//if(arbitration_lost)					//This is software part to program the control register so that it will generate stop 			//scl_main_state<=scl_main_idle;		//and will go in idle state.So removing all clauses except detect stop.		if(detect_stop)		begin			scl_main_state<=scl_main_idle;			sm_stop_sig<=1'b0;		end			else 			scl_main_state<=scl_tx_data;		//else		//begin			//if(master_slave)				//sm_stop_sig<=1'b1;		//scl_main_state<=scl_main_idle;		//end	endcaseendend//Start and stop detect process//////////////////////////////always@(sda_in or scl_main_state)begin	if(rst || h_rst)		detect_start_sig<=1'b0;	else if(!sda_in && scl_in)		detect_start_sig<=1'b1;	else if(scl_address_shift)		detect_start_sig<=1'b0;	else		detect_start_sig<=1'b0;endalways@(posedge sda_in or posedge detect_start)begin	if(rst || h_rst)		detect_stop_sig<=1'b0;	else if(detect_start)		detect_stop_sig<=1'b0;	else if(scl_in)		detect_stop_sig<=1'b1;	//else if(detect_start)		//detect_stop_sig<=1'b0;	else		detect_stop_sig<=1'b0;end//generate a delay version of byte_trans signal//This will be used for detecting falling edge of byte_transalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		byte_trans_delay_sig <= 1'b0;	else	begin		byte_trans_delay_sig <= byte_trans;		byte_trans_fall_sig <= byte_trans_delay && !byte_trans;	endend		//Processor status bits///////byte_trans bit//This indicate data is being transferred,This bit will be one only after all 8 bits has//been tranferred.i.e on rising pulse of SCL in ack cycle.always@(negedge scl_in or posedge rst or posedge halt_rst or posedge core_rst or posedge h_rst)begin	if(rst || h_rst)		byte_trans_sig<=1'b0;	else if(halt_rst)		byte_trans_sig <= 1'b0;	else if(bit_cnt == 8'b0000_1000)				byte_trans_sig<=1'b1;	else if(halt_rst || core_rst)			// after core_rst negate byte_trans bit		byte_trans_sig<=1'b0;end//bus_busy//This indicates that communication is in progress and bus in not free.//This bit will be set on detection of start and will be cleared on STOPalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		bb_sig<=1'b0;	else	begin		if(detect_start)			bb_sig<=1'b1;		if(detect_stop || core_rst)			bb_sig<=1'b0;	endend//slave_addressed bit//This indicates that slave has been addressed,and after sending ack//core will switch to slave mode.//This bit will be set if adds matched in add ack state.always@(posedge clk or posedge rst or posedge h_rst)begin	if(rst)				//Removing h_rst	slave_addressed_sig<=1'b0;	//else if(scl_main_state == scl_ack_address)	else if(byte_trans)	slave_addressed_sig<=addr_match;	else	slave_addressed_sig<=slave_addressed;	//slave_addressed_sig<= 1'b0;end//set address match bit if address reg matches with shift register output/*always@(negedge scl or posedge rst)begin	if(rst)		addr_match_sig<=1'b0;	else if( slave_add[7:1] == add_reg[7:1])		addr_match_sig <=1'b1;	else		addr_match_sig<=1'b0;end*/assign addr_match = slave_add[7:1] == add_reg[7:1]? 1'b1:1'b0;assign add_reg_ld = 1'b0;//Slave read write//This bit indicates slave has been addressed,this indicates//read or write bit sent by processor.always@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		slave_rw_sig<=1'b0;	else if(scl_main_state == scl_ack_address)		slave_rw_sig<=add_reg[0];end//interrupt pending//This will cause an interrupt to processor if interrupt enable is set//This bit will be set in following circumstances://1):Byte transfer has been completed.//2):Arbitration lost.//3):slave has been addressed and and bytes have been transferred.//4):Time out condition has been reached.//5):Repeated start condition.//Only processor can clear the interrupt.always@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)	inter_sig<=1'b0;		else	begin		//if(interrupt_rst)		//inter_sig<=1'b0;				if(inter_rst)		inter_sig<=1'b0;			//in below else if condition anding byte_trans with master_slave also removing add_reg[]  condition in next clause				else if((byte_trans && master_slave) || arbitration_lost || (slave_addressed && !master_slave && byte_trans) || rep_start)		inter_sig<=1'b1;							//else			//interrupt need to get cleared by processor,so do not reset in else condition		//inter_sig<=1'b0;			endend//generate delay version of detect_stopalways@(posedge clk or posedge rst or posedge h_rst)beginif(rst || h_rst)d_detect_stop_sig <= 1'b0;elsebegind1_detect_stop_sig <= detect_stop;d_detect_stop_sig <= d1_detect_stop_sig;endendalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)	halt_sig <= 1'b0;		else	begin		if(halt_rst)			halt_sig<=1'b0;			else if(byte_trans && master_slave)			halt_sig<=1'b1;	endend//acknoweldege recieve//This bit indicates the data on SDA line during ack cycle.always@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		ack_rec_sig<=1'b0;	else if((scl_main_state == scl_wait_ack) || (scl_main_state == scl_ack_address) || (scl_main_state == scl_send_ack))		ack_rec_sig<=sda_in;end//Setting control bits of shift registers and counters////////////////////////////////////////////////////////Address shift register will just receive the data after start //condition detection.It wont be get loaded.While data shift register//will receive as well as transmit the data.//address shift register enable bitalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		add_reg_enable_sig<=1'b0;	else if(detect_start || scl_main_state == scl_address_shift)		add_reg_enable_sig<=1'b1;	else		add_reg_enable_sig<=1'b0;end//Data shift register.//This register will be enabled every time when it is either transmitting or receiving the data.   always @(posedge clk or posedge rst or posedge h_rst)  begin    if (rst || h_rst)    begin      data_reg_en_sig <= 1'b0;      data_reg_ld_sig <= 1'b0;    end    else    begin      if (((master_slave && scl_main_state == scl_address_shift) || (scl_main_state ==          scl_rx_data) || (scl_main_state == scl_tx_data)))        data_reg_en_sig <= 1'b1;      else        data_reg_en_sig <= 1'b0;		 /*if ((master_slave && scl_main_state == scl_idle) || (scl_main_state ==          scl_wait_ack) || (scl_main_state == scl_ack_address &&          !add_reg[0] && !master_slave) || (scl_main_state == scl_ack_address &&          master_rw && master_slave))*/		if(((scl_main_state == scl_main_idle) || byte_trans) && data_en)		data_reg_ld_sig <= 1'b1;	 else        data_reg_ld_sig <= 1'b0;     end 		  end//logic for generating control bits for bit counter////////////////////////////////////////////////////////////////////////////////////////////////assign bit_cnt_enable = ((scl_main_state == scl_address_shift) || (scl_main_state == scl_rx_data) || (scl_main_state == scl_tx_data));assign bit_cnt_rst = ((scl_main_state == scl_main_idle) || (scl_main_state == scl_send_ack) || (scl_main_state == scl_wait_ack) || (scl_main_state == scl_ack_address));///////////////////////////////////////////////////////////////////////////////////////////////implementation of timer counteralways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)	time_cnt<=8'b0000_0000;	else if(!scl_in) 	time_cnt<=time_cnt + 1'b1;	else	time_cnt<=8'b0000_0000;endalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)	begin		core_rst_sig<=1'b0;		time_out_sig<=1'b0;	end	else if((time_cnt == time_out_reg) & bb)	begin		core_rst_sig <= 1'b1;		time_out_sig <= 1'b1;	end	/*else if((time_cnt == time_out_reg) && (scl_state == scl_idle))	begin		core_rst_sig <= 1'b0;		time_out_sig <= 1'b1;	end*/	else	begin			core_rst_sig <= 1'b0;		time_out_sig <= 1'b0;	end	end//Process for assigning Master and slave SDA.always@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		master_sda_sig<=1'b1;	else if((scl_main_state == scl_address_shift) || (scl_main_state == scl_tx_data))		master_sda_sig<=serial_out;	else if(scl_main_state == scl_send_ack)		master_sda_sig<=ack;	else		master_sda_sig<=1'b1;endalways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		slave_sda_sig<=1'b1;	else if(scl_main_state == scl_tx_data)		slave_sda_sig<=serial_out;	else if((addr_match && (scl_main_state == scl_ack_address)) || (scl_main_state == scl_send_ack))		slave_sda_sig<=ack;	else		slave_sda_sig<=1'b1;end//assigning SCL and SDA lines in output conditions.assign scl_oe = master_slave ? scl_out : 1'b1;assign sda_sig = (((master_slave == 1'b1 && sda_out == 1'b0) ||		 (master_slave == 1'b0 && slave_sda == 1'b0) || stop_scl) ? 1'b1 : 1'b0);assign sda_oe = (sda_sig ?1'b0 : 1'b1);//Presenting data on data_register which is for processoralways@(posedge clk or posedge rst or posedge h_rst)begin	if(rst || h_rst)		i2c_up<=8'b00000000; 	else if(scl_main_state == scl_send_ack)		i2c_up<=shift_reg;	else		i2c_up<=i2c_up;end//This process will set arbitration lost signal////////////////////////////////////////////// //   This process checks the master's outgoing SDA with the incoming SDA to determine  //   if control of the bus has been lost. SDA is checked only when SCL is high  //   and during the states IDLE, ADD_SHIFT, and TX_DATA to insure that START and STOP  //   conditions are not set when the bus is busy. Note that this is only done when Master.   always @( posedge (clk) or posedge (rst) or posedge (h_rst) )  begin    if (rst || h_rst)    begin      arbitration_lost_sig <= 1'b0;     end    else    begin      if (scl_main_state == scl_idle)      begin        arbitration_lost_sig <= 1'b0;      end      else if ((master_slave))        //   only need to check arbitration in master mode        //   check for SCL high before comparing data         if ((scl_in && scl_oe && (scl_main_state == scl_address_shift || scl_main_state            == scl_tx_data || scl_main_state == scl_idle)))          //   when master, will check bus in all states except ACK_ADDR and WAIT_ACK          //   this will insure that arb_lost is set if a start or stop condition          //   is set at the wrong time         	//if(sda_in == 1'b0 && sda_oe == 1'b1) || (detect_stop			 if (sda_in == 1'b0 && sda_oe == 1'b1)          begin            arbitration_lost_sig <= 1'b1;                      end          else          begin            arbitration_lost_sig <= 1'b0;                      end         else        begin          arbitration_lost_sig <= arbitration_lost;        end      end   end//setting the arbitration lost bit of status register//////////////////////////////////////////////////////this bit will be set when:	//arbiration has lost.	//core is in master mode and a generate strat condition has detected while bus is busy 	//or a stop conditioin has been detected when not requested	//or a repeate start has been detected when in slave mode.always@(posedge clk or posedge rst or posedge core_rst or posedge h_rst)begin	if(rst || h_rst)		arb_lost_sig<=1'b0;	else	begin		if(arb_rst)		arb_lost_sig<=1'b0;		else if(master_slave)		begin			if((arbitration_lost)||(bus_busy && gen_start))						arb_lost_sig<=1'b1;		end			else if(rep_start)			arb_lost_sig<=1'b1;		//else if(core_rst && master_slave)			//arb_lost_sig<=1'b0;		else			arb_lost_sig<=1'b0;	endendalways@(posedge clk or posedge rst or posedge h_rst)beginif(rst || h_rst)	rep_start_sig<=1'b0;else if(scl_main_state == scl_address_shift || scl_main_state == scl_ack_address || scl_main_state == scl_send_ack || scl_main_state == scl_wait_ack)	rep_start_sig<=1'b0;else	rep_start_sig<=rep_start;end	endmodule 																																				

⌨️ 快捷键说明

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