串口读写IIC器件 FPGA Verilog HDL

2 篇文章 0 订阅
2 篇文章 0 订阅

串口读写IIC器件 FPGA Verilog HDL

IIC总线协议实现:

`include "config.v"
module I2C(
    clk,               //system clk 50MHZ
	rstn,              //active low
	data_in,           
   data_out,
	sda,
	scl,
	wr,               //wr=0   write; wr=1  read
	fail,
	req,
	address,
	wr_done,
	rd_done
);


    input clk;
	input rstn;
	input [7:0]data_in;
	input wr;
	input req;
	input [7:0] address;
	
	output [0:0]scl;
	output reg[7:0] data_out;
	
	inout sda;
	output fail;
	output rd_done;
	output wr_done;
	
	reg [7:0] clk_cnt;
	
	wire sda_in;
	reg sda_out;
	
	reg [29:0] state;
	
	reg [0:0]  sda_mode;
	wire clk_en;
	
	parameter IN   =0,
	          OUT  =1;
				 
				 
	parameter         idle      =30'b00_0000_0000_0000_0000_0000_0000_0001,
	                  start     =30'b00_0000_0000_0000_0000_0000_0000_0010,
					  mode0     =30'b00_0000_0000_0000_0000_0000_0000_0100,
					  mode1     =30'b00_0000_0000_0000_0000_0000_0000_1000,
					  mode2     =30'b00_0000_0000_0000_0000_0000_0001_0000,
					  mode3     =30'b00_0000_0000_0000_0000_0000_0010_0000,
					  mode4     =30'b00_0000_0000_0000_0000_0000_0100_0000,
					  mode5     =30'b00_0000_0000_0000_0000_0000_1000_0000,
					  mode6     =30'b00_0000_0000_0000_0000_0001_0000_0000,
					  mode7     =30'b00_0000_0000_0000_0000_0010_0000_0000,
					  ack_mode  =30'b00_0000_0000_0000_0000_0100_0000_0000,
					  addr0     =30'b00_0000_0000_0000_0000_1000_0000_0000,
					  addr1     =30'b00_0000_0000_0000_0001_0000_0000_0000,
					  addr2     =30'b00_0000_0000_0000_0010_0000_0000_0000,
					  addr3     =30'b00_0000_0000_0000_0100_0000_0000_0000,
					  addr4     =30'b00_0000_0000_0000_1000_0000_0000_0000,
					  addr5     =30'b00_0000_0000_0001_0000_0000_0000_0000,
					  addr6     =30'b00_0000_0000_0010_0000_0000_0000_0000,
					  addr7     =30'b00_0000_0000_0100_0000_0000_0000_0000,
					  ack_addr  =30'b00_0000_0000_1000_0000_0000_0000_0000,
					  bit0      =30'b00_0000_0001_0000_0000_0000_0000_0000,      
					  bit1      =30'b00_0000_0010_0000_0000_0000_0000_0000, 
					  bit2      =30'b00_0000_0100_0000_0000_0000_0000_0000, 
					  bit3      =30'b00_0000_1000_0000_0000_0000_0000_0000, 
					  bit4      =30'b00_0001_0000_0000_0000_0000_0000_0000, 
					  bit5      =30'b00_0010_0000_0000_0000_0000_0000_0000, 
					  bit6      =30'b00_0100_0000_0000_0000_0000_0000_0000, 
					  bit7      =30'b00_1000_0000_0000_0000_0000_0000_0000, 
					  ack_bit   =30'b01_0000_0000_0000_0000_0000_0000_0000,
					  stop      =30'b10_0000_0000_0000_0000_0000_0000_0000;    
					  
   //generate clk 400khz
	always@(posedge clk)
      if(!rstn)
		   clk_cnt <=8'd0;
		else if(clk_en)
		   begin
			   if(clk_cnt==`COUNT_MAX)
				  clk_cnt <=8'd0;
				else
				  clk_cnt <=clk_cnt + 1'b1;
			end
		else
		   clk_cnt <=8'd0;
			
	//wire neg=(clk_cnt==`NEG)?1:0;            //negedge of the scl_clk
	wire      h_half   =(clk_cnt==h_half);      
	wire      l_half   =(clk_cnt==l_half);  
   wire      scl_clk  =(clk_cnt <`HALF);
   assign    scl      =(clk_en&scl_clk)|(!clk_en);
	
	//control sda direction
    assign sda=(sda_mode==OUT)?sda_out:1'bz;
	assign sda_in=(sda_mode==IN)?sda:1'bz;
	wire    full=(clk_cnt==`COUNT_MAX);

   //state control	
	always@(posedge clk)
      if(!rstn)
	      state <=idle;
		else
	      case(state)
		   idle:
		      if(req)
			      state <=start;
				else
			      state <=state;
			start:   //at the same time start clock generator
			      if(full)
					   state <=mode0;
					else
					   state <=state;
			mode0:
			      if(full)
		            state <=mode1;
					else
					   state <=state;
			mode1:
			      if(full)
		            state <=mode2;
					else
					   state <=state;
			mode2:
			      if(full)
		            state <=mode3;
					else
					   state <=state;
			mode3:
		         if(full)
					  state <=mode4;
					else
					  state <=state;
			mode4:
		         if(full)
					  state <=mode5;
					else
					  state <=state;
			mode5:
			      if(full)
		            state <=mode6;
					else
					   state <=state;
			mode6:
		         if(full)
					  state <=mode7;
					else
					  state <=state;
			mode7:
			      if(full)
		            state <=ack_mode;	
					else
					   state <=state;
			ack_mode:
			      if(h_half)
					   begin
						   if(sda_in==1'b1)
							   state <=addr0;
							else
							   state <=stop;
						end
					else
					   state <=state;
			addr0:
			      if(full)
					   state <=addr1;
					else
					   state <=state;
			addr1: 
			      if(full)
					   state <=addr2;
					else
					   state <=state;
			addr2:
			      if(full)
					   state <=addr3;
					else
					   state <=state;
			addr3:  
			      if(full)
					   state <=addr4;
					else
					   state <=state;
			addr4:
			      if(full)
					   state <=addr5;
					else
					   state <=state;
			addr5:
			      if(full)
					   state <=addr6;
					else
					   state <=state;
			addr6:
			      if(full)
					   state <=addr7;
					else
					   state <=state;
			addr7:
			      if(full)
					   state <=ack_addr;
					else
					   state <=state;
		   ack_addr:
			      if(h_half)
					   begin
			            if(sda_in==1'b0)
					         state <=bit0;
					      else
					         state <=stop;
						end
				   else
					   state <=state;
		   bit0:
			      if(full)
					   state <=bit1;
					else
					   state <=bit2;
			bit1:
			      if(full)
					   state <=bit2;
					else
					   state <=state;
			bit2:
			      if(full)
					   state <=bit3;
					else
					   state <=state;
			bit3:
			      if(full)
					   state <=bit4;
					else
					   state <=state;
			bit4:
			      if(full)
					   state <=bit5;
					else
					   state <=state;
			bit5:
			      if(full)
					   state <=bit6;
					else
					   state <=state;
			bit6:
			      if(full)
					   state <=bit7;
					else
					   state <=state;			
			bit7:
			      if(full)
					   state <=ack_bit;
					else
					   state <=state;
			ack_bit:
			        if((!wr)&h_half)
					      begin
			               if(sda_in==1'b0)
					            state  <=stop;
					         else
					            state  <=stop;
							end
                    else if(wr&l_half)
                           state <=stop;					
					else
						   state <=state;
			stop:
			      if(full)
					   state <=idle;
					else
					   state <=state;
			default: state  <=stop;
		endcase
			
	always@(posedge clk)
	if(!rstn)
	begin
	    sda_mode <=OUT;
		sda_out  <=1'b1;
		data_out <=8'b0;
	end
	else
	    case(state)
		    idle:
			        begin
			        sda_mode <=OUT;
				     sda_out  <=1'b1;
			        end
		    start:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b0;
					    else
					    sda_out <=1'b1;
			        end
		    mode0:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b1;
					    else
					    sda_out <=sda_out;
			        end
		    mode1:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b0;
					    else
					    sda_out <=sda_out;
			        end
		    mode2:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b1;
					    else
					    sda_out <=sda_out;
			        end
		    mode3:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b0;
					    else
					    sda_out <=sda_out;
			        end
		    mode4:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b1;
					    else
					    sda_out <=sda_out;
			        end
		    mode5:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b0;
					    else
					    sda_out <=sda_out;
			        end
		    mode6:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=1'b0;
					    else
					    sda_out <=sda_out;
			        end
		    mode7:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=wr;
					    else
					    sda_out <=sda_out;
			        end
		    ack_mode:
			        begin
			        sda_mode <=IN;
			        end
		    addr0:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[7];
					    else
					    sda_out <=sda_out;
			        end					
		    addr1:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[6];
					    else
					    sda_out <=sda_out;
			        end	
		    addr2:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[5];
					    else
					    sda_out <=sda_out;
			        end	
		    addr3:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[4];
					    else
					    sda_out <=sda_out;
			        end	
		    addr4:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[3];
					    else
					    sda_out <=sda_out;
			        end	
		    addr5:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[2];
					    else
					    sda_out <=sda_out;
			        end	
		    addr6:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[1];
					    else
					    sda_out <=sda_out;
			        end	
		    addr7:
			        begin
			        sda_mode <=OUT;
				        if(l_half)
					    sda_out <=address[0];
					    else
					    sda_out <=sda_out;
			        end						
		   ack_addr:
			        begin
			        sda_mode <=IN;
			        end	
            bit0:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[7]  <=sda_in;
							else
							data_out[7]  <=data_out[7];
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[7];
							   else
							   sda_out   <=sda_out;
                        end						
            bit1:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[6]  <=sda_in;
							else
							data_out[6]  <=data_out[6];
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[6];
							   else
							   sda_out   <=sda_out;
                        end	
            bit2:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[5]  <=sda_in;
							else
							data_out[5]  <=data_out[5];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[5];
							   else
							   sda_out   <=sda_out;
                        end	
            bit3:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[4]  <=sda_in;
							else
							data_out[4]  <=data_out[4];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[4];
							   else
							   sda_out   <=sda_out;
                        end	
            bit4:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[3]  <=sda_in;
							else
							data_out[3]  <=data_out[3];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[3];
							   else
							   sda_out   <=sda_out;
                        end	
            bit5:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[2]  <=sda_in;
							else
							data_out[2]  <=data_out[2];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[2];
							   else
							   sda_out   <=sda_out;
                        end	
            bit6:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[1]  <=sda_in;
							else
							data_out[1]  <=data_out[1];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[1];
							   else
							   sda_out   <=sda_out;
                        end	
            bit7:
                    if(wr)//read
					    begin
                            sda_mode     <=IN;
                            if(h_half)
					    	data_out[0]  <=sda_in;
							else
							data_out[0]  <=data_out[0];							
                        end
                   	else//write
                        begin
                            sda_mode     <=OUT;
							   if(l_half)
							   sda_out   <=data_in[0];
							   else
							   sda_out   <=sda_out;
                        end	
            ack_bit:
						if(!wr)
                            sda_mode  <=IN;
						else
						    begin
							sda_mode  <=OUT;
							if(l_half)
							sda_out   <=1'b1;
							else
							sda_out   <=sda_out;
							end        									
            stop:
                if(h_half)//閹峰鐝
				    begin
					sda_mode    <=OUT;
					sda_out     <=1;
					end
				else if(!h_half)//閹峰缍
				    begin
					sda_mode    <=OUT;
					sda_out     <=0;					
					end
		    default:begin   
						sda_out   <=1'b1;
						sda_mode  <=OUT;
                        data_out  <=8'd0;						
			        end
	    endcase
								
   assign   clk_en       =(state==idle);
   assign   wr_done      =(state==ack_bit)&(h_half)&(sda_in==1'b0);
   assign   fail         =((state==ack_mode)&(h_half)&(sda_in!=1'b0))|
                          ((state==ack_addr)&(h_half)&(sda_in!=1'b0))|
                          ((state==ack_bit)&(h_half)&(sda_in!=1'b0));			 
   assign   rd_done     =(state==stop);	
endmodule 

config 目录

`define SYS_CLK  50_000_000
`define SCL_CLK  400_000

`define COUNT_MAX (`SYS_CLK/`SCL_CLK)

`define HALF  (`COUNT_MAX/2 -1)

`define H_HALF  (`HALF/2)
`define NEG     (`HALF +1)
`define L_HALF  (`H_HALF+NEG)

串口接收模块:

//-----------------------------------------
//串口通信数据接收模块 

module uart_data_rx(
   clk,
	rst_n,
	data_in,
	baud_set,
	
	data_byte,
	rx_done
);

  input clk;
  input rst_n;
  input data_in;
  input [2:0] baud_set;
  
  output reg [7:0] data_byte;
  output reg rx_done;
  
  reg data_reg_a,data_reg_b,data_reg_c,data_reg_d;
  
  reg [8:0] bps_dr;
  reg [8:0] div_cnt;
  reg bps_clk;
  reg [7:0] bps_cnt;
  reg [2:0] r_data_byte [7:0];
  reg [7:0] tmp_data_byte;
  reg [2:0] START_BIT,STOP_BIT;
  reg uart_state;

//-----------------------------------------
//同步数据至系统时钟域
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   begin data_reg_a <=1'b0;data_reg_b <=1'b0;end
	 else 
		begin data_reg_a <=data_in;data_reg_b <=data_reg_a;end
		
//------------------------------------------
//数据寄存
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	  begin data_reg_c <=1'b0;data_reg_d <=1'b0;end
	 else
	  begin data_reg_c <=data_reg_b;data_reg_d<=data_reg_c;end
	  
//--------------------------------------------
//检测数据下降沿,以判断数据起始位
 wire neg=(!data_reg_c)&&(data_reg_d);
 
 
//--------------------------------------------
//波特率查找表的生成
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   bps_dr <=9'd0;
	 else 
	   begin
		case(baud_set)
	   0:bps_dr <=9'd324;//9600
		1:bps_dr <=9'd162;//19200
		2:bps_dr <=9'd80;//38400
		3:bps_dr <=9'd53;//57600
		4:bps_dr <=9'd26;//115200
		default:bps_dr <=9'd324;
		endcase
		end
		
//-------------------------------------------
//生成采样时钟
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   div_cnt <= 9'd0;
	 else if(uart_state)
	   begin
	       if(div_cnt==bps_dr)
		      div_cnt <=9'd0;
			 else
			   div_cnt <=div_cnt +1'b1;
		end
	 else
	   div_cnt <=9'd0;
		
//---------------------------------------------
//波特率时钟的生成
  always@(posedge clk or negedge rst_n)
   if(!rst_n)
	  bps_clk <=1'b0;
	else if(div_cnt==9'd1)
	  bps_clk <=1'b1;
	else
	  bps_clk <=1'b0;
	  
//----------------------------------------------
//采样时钟计数器
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   bps_cnt <=8'd0;
	 else if(bps_cnt==8'd159||(bps_cnt==8'd12&&(START_BIT >2)))
	 //START_BIT >2 意味着起始位错误
	   bps_cnt <=8'd0;
	 else if(bps_clk)
	   bps_cnt <=bps_cnt +1'b1;
	 else
	   bps_cnt <=bps_cnt;
		
//----------------------------------------------
//发送完成信号的产生
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   rx_done <= 1'b0;
	 else if(bps_cnt==8'd159)
	   rx_done <=1'b1;
	 else
	   rx_done <=1'b0;
		
//--------------------------------------------
//采样数据接收模块
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   begin
		     START_BIT <=3'b0;
			  r_data_byte[0]<=3'd0;
			  r_data_byte[1]<=3'd0;
			  r_data_byte[2]<=3'd0;
			  r_data_byte[3]<=3'd0;
			  r_data_byte[4]<=3'd0;
		     r_data_byte[5]<=3'd0;
			  r_data_byte[6]<=3'd0;
			  r_data_byte[7]<=3'd0;
			  STOP_BIT <=3'b0;
		end
	else if(bps_clk)begin
	case(bps_cnt)
	0:begin
	       START_BIT <=3'b0;
			  r_data_byte[0]<=3'd0;
			  r_data_byte[1]<=3'd0;
			  r_data_byte[2]<=3'd0;
			  r_data_byte[3]<=3'd0;
			  r_data_byte[4]<=3'd0;
		     r_data_byte[5]<=3'd0;
			  r_data_byte[6]<=3'd0;
			  r_data_byte[7]<=3'd0;
			  STOP_BIT <=3'b0;
	   end
	6,7,8,9,10,11    :START_BIT <=START_BIT +data_reg_d;
	22,23,24,25,26,27:r_data_byte[0] <= r_data_byte[0] +data_reg_d;
	38,39,40,41,42,43:r_data_byte[1] <= r_data_byte[1] +data_reg_d;
	54,55,56,57,58,59:r_data_byte[2] <= r_data_byte[2] +data_reg_d;
	70,71,72,73,74,75:r_data_byte[3] <= r_data_byte[3] +data_reg_d;
	86,87,88,89,90,91:r_data_byte[4] <= r_data_byte[4] +data_reg_d;
	102,103,104,105,106,107:r_data_byte[5] <= r_data_byte[5] +data_reg_d;
	118,119,120,121,122,123:r_data_byte[6] <= r_data_byte[6] +data_reg_d; 
   134,135,136,137,138,139:r_data_byte[7] <= r_data_byte[7] +data_reg_d;
   150,151,152,153,154,155:STOP_BIT <= STOP_BIT+data_reg_d;	
	default:
	       begin
			 START_BIT <=START_BIT;
			 r_data_byte[0]<=r_data_byte[0];
			 r_data_byte[1]<=r_data_byte[1];
			 r_data_byte[2]<=r_data_byte[2]; 
	       r_data_byte[3]<=r_data_byte[3];
	       r_data_byte[4]<=r_data_byte[4];
          r_data_byte[5]<=r_data_byte[5];
		    r_data_byte[6]<=r_data_byte[6];
	       r_data_byte[7]<=r_data_byte[7];
			 STOP_BIT <=STOP_BIT;
			 end
   endcase
  end

  
//----------------------------------------------
//接收数据判决
  	always@(posedge clk or negedge rst_n)
	if(!rst_n)
		data_byte <= 8'd0;
	else if(bps_cnt == 8'd159)begin
		data_byte[0] <= r_data_byte[0][2];
		data_byte[1] <= r_data_byte[1][2];
		data_byte[2] <= r_data_byte[2][2];
		data_byte[3] <= r_data_byte[3][2];
		data_byte[4] <= r_data_byte[4][2];
		data_byte[5] <= r_data_byte[5][2];
		data_byte[6] <= r_data_byte[6][2];
		data_byte[7] <= r_data_byte[7][2];
	end
	
	
//----------------------------------------------
//uart_state 信号产生
  always@(posedge clk or negedge rst_n)
    if(!rst_n)
	   uart_state <=1'b0;
	 else if(neg)
	   uart_state <=1'b1;
	 else if(rx_done||(bps_cnt==8'd12)&&(START_BIT >2))
	   uart_state <=1'b0;
	 else 
	   uart_state <=uart_state;  
endmodule 

串口发送模块:

module uart_tx(
    Send_En,
    Clk,
	 Rst_n,
    data_byte,
	 baud_set,
		 
	RS232_Tx,
   Tx_Done,
   uart_state
);

  input Clk;
  input Rst_n;
  input Send_En;
  input [7:0] data_byte;
  input [2:0] baud_set;
  
  output reg RS232_Tx;
  output reg Tx_Done;
  output reg uart_state;
  
  reg [15:0] bps_DR;//波特率暂存寄存器
  
  reg [15:0] div_cnt;//分频计数器
  reg bps_clk;//波特率时钟
  
  reg [3:0] bps_cnt;
  
  reg [7:0]  r_data_byte;
  
  localparam START_BIT=1'b0;
  localparam STOP_BIT=1'b1;
  
  
//波特率查找表
  always@(posedge Clk or negedge Rst_n)
     if(!Rst_n)
	    bps_DR <= 16'd5207;//默认波特率为9600
	  else begin
	    case(baud_set)
		      0:bps_DR <=16'd5207;//9600
				1:bps_DR <=16'd2604;//19200
				2:bps_DR <=16'd1302;//38400
				3:bps_DR <=16'd867;//57600
				4:bps_DR <=16'd433;//115200
				default:bps_DR <=16'd5207;
		 endcase
		 
	  end
	  
//分频计数
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   div_cnt <= 16'd0;
	else if(uart_state)begin//当发送状态时计数,其他时候不使能计数器
	       if(div_cnt==bps_DR)
			    div_cnt <=16'd0;
			 else
			    div_cnt <= div_cnt+1'b1;
	end 
   else
      div_cnt<=16'd0;
	
//bps_clk 生成
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   bps_clk <=1'b0;
	 else if(div_cnt==16'd1)
	  bps_clk <=1'b1;
	 else
	  bps_clk<=1'b0; 
	  
//字节计数
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   bps_cnt <=4'd0;
	 else if(bps_cnt==4'd11)
	   bps_cnt <=4'd0;
	 else if(bps_clk)
	   bps_cnt <=bps_cnt+1'b1;
	 else
	 bps_cnt <=bps_cnt;
	 
//字节发送完毕信号产生
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   Tx_Done <=1'b0;
	 else if(bps_cnt==11)
	  Tx_Done <=1'b1;
	 else 
	  Tx_Done <= 1'b0;
	 
//发送状态产生
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   uart_state <= 1'b0;
	 else if(Send_En)
	   uart_state <=1'b1;
	 else if(bps_cnt==4'd11)
	   uart_state <=1'b0;
	 else 
	   uart_state <=uart_state;
		
//数据暂存寄寄存器
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   r_data_byte <= 8'd0;
	 else if(Send_En)
	   r_data_byte <=data_byte;
	 else
	   r_data_byte <= r_data_byte;
		
//传输数据控制
  always@(posedge Clk or negedge Rst_n)
    if(!Rst_n)
	   RS232_Tx <=1'b1;
	 else begin
	   case(bps_cnt)
	       0:RS232_Tx <=1'b1;
			 1:RS232_Tx <=START_BIT;
			 2:RS232_Tx <=r_data_byte[0];
			 3:RS232_Tx <=r_data_byte[1];
			 4:RS232_Tx <=r_data_byte[2];
			 5:RS232_Tx <=r_data_byte[3];
			 6:RS232_Tx <=r_data_byte[4];
			 7:RS232_Tx <=r_data_byte[5];
			 8:RS232_Tx <=r_data_byte[6];
			 9:RS232_Tx <=r_data_byte[7];
			 10:RS232_Tx <=STOP_BIT;
			 default:RS232_Tx <=1'b1;
		endcase
	end
endmodule 

控制模块:

module ctrl(
   clk,
	rstn,
	rx_o,
	rx_done,
	tx_done,
	tx_in,
	tx_en,
	addr,
	iic_in,
	iic_out,
	req,
	wr,
	wr_done,
	rd_done,
	fail
);

   input clk;
   input rstn;
   input [7:0]rx_o;
   input rx_done;
	input tx_done;
   output [7:0] addr;
   input wr_done;
   input rd_done;
	input fail;
	
	output [7:0]iic_in;
	input [7:0] iic_out;
   
   output [7:0]tx_in;
   output tx_en;
	output req;
	output wr;

   reg [1:0] cnt;
	reg [23:0] data_reg;
	
	always@(posedge clk or negedge rstn)
	   if(!rstn)
		   cnt <=2'd0;
		else if(rx_done)
		   begin
			   if(cnt==2'd2)
			      cnt <=2'd0;
				else
				   cnt <=cnt + 1'b1;
			end
		else
		   cnt <=cnt;
			
			
	always@(posedge clk or negedge rstn)
	   if(!rstn)
		   data_reg <=24'd0;
		else if(rx_done)
		   data_reg <=(data_reg << 8)|({16'b0,rx_o});
		else
		   data_reg <=data_reg;
			
	assign addr=data_reg[15:8];
	assign req =(cnt==2'd2)&(rx_done)&(data_reg[23:20]==4'hf);
	assign iic_in=data_reg[7:0];
	assign wr=|data_reg[19:16];
	
	
	assign tx_in=iic_out;
	
	wire tx_reg;
   assign tx_reg=wr&(wr_done|rd_done)&(!fail);
	
	reg tx_en_reg;
   always@(posedge clk or negedge rstn)
      if(!rstn)
	      tx_en_reg <=1'b0;
	   else
         tx_en_reg <=tx_reg;
			
	assign tx_en=(!tx_en_reg)&tx_reg;		



endmodule 

顶层模块:

module top(
   clk,
	rstn,
	tx,
	rx,
	scl,
	sda
);

   input clk;
   input rstn;
   input rx;
   
   inout sda;
   
   output tx;
   output scl;
   
   wire [7:0] receive_data;
   wire rx_done;
   wire tx_done;
   wire en;
   wire wr;
   wire req;
   wire [7:0] address;
   wire [7:0] iic_in;
   wire [7:0] iic_out;
   wire wr_done;
   wire rd_done;
   wire fail;
   wire [7:0] tx_in;

I2C I2C(
   .clk(clk),               //system clk 50MHZ
	.rstn(rstn),              //active low
	.data_in(iic_in),           
   .data_out(iic_out),
	.sda(sda),
	.scl(scl),
	.wr(wr),               //wr=0   write; wr=1  read
	.fail(fail),
	.req(req),
	.address(address),
	.wr_done(wr_done),
	.rd_done(rd_done)
);

uart_tx uart_tx(
   .Send_En(en),
   .Clk(clk),
	.Rst_n(rstn),
   .data_byte(tx_in),
	.baud_set(3'd0),	 
	.RS232_Tx(tx),
   .Tx_Done(tx_done),
   .uart_state()
);

uart_data_rx uart_data_rx(
   .clk(clk),
	.rst_n(rstn),
	.data_in(rx),
	.baud_set(3'd0),
	.data_byte(receive_data),
	.rx_done(rx_done)
);


ctrl ctrl(
   .clk(clk),
	.rstn(rstn),
	.rx_o(receive_data),
	.rx_done(rx_done),
	.tx_done(tx_done),
	.tx_in(tx_in),
	.tx_en(en),
	.addr(address),
	.iic_in(iic_in),
	.iic_out(iic_out),
	.req(req),
	.wr(wr),
	.wr_done(wr_done),
	.rd_done(rd_done),
	.fail(fail)
);


endmodule 

综合后的map:
top  lion A

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值