Xilinx FPGA:vivado fpga与EEPROM的IIC通信,串口显示数据,含使用debug教程

一、实验要求

实现FPGA与EEPROM的通信,要求FPGA对EEPROM实现先“写”后“读”,读出的值给uart发送端并显示到电脑上,按下按键1让fpga对EEPROM写入数据;按下按键2让fpga读出对EEPROM写入过的数据。

二、信号流向图

三、程序设计

(1)按键消抖模块

`timescale 1ns / 1ps
module key(
  input                     sys_clk     ,
  input                     rst_n       ,
  (* MARK_DEBUG="true" *)input                     key1        ,
  (* MARK_DEBUG="true" *)input                     key2        ,
  (* MARK_DEBUG="true" *)output                    key_flag_1  ,
  (* MARK_DEBUG="true" *)output                    key_flag_2
     
    );
  parameter                delay = 20'd1_000_000 ;        //20ms=20_000_000  20_000_000/20 == 10_000_00
  reg[19:0]                 cnt1               ;
  reg[19:0]                 cnt2               ;
  
  always@(posedge sys_clk )
       if(!rst_n)
          cnt1 <= 0 ;
       else if ( key1 == 0 )begin
            if ( cnt1 == delay -1 )
                 cnt1 <= cnt1 ;
            else
                 cnt1 <= cnt1 +1 ;
       end
       else
       cnt1 <= 0 ;
  
   always@(posedge sys_clk )
        if(!rst_n)
           cnt2 <= 0 ;
        else if ( key2 == 0 )begin
             if ( cnt2 == delay -1 )
                  cnt2 <= cnt2 ;
             else
                  cnt2 <= cnt2 +1 ;
        end
        else
        cnt2 <= 0 ;
        
        
assign  key_flag_1 = ( cnt1 == delay -2 )?1:0 ;
assign  key_flag_2 = ( cnt2 == delay -2 )?1:0 ;


endmodule

(2)数据产生模块

`timescale 1ns / 1ps
module data_generate(
    input                        sys_clk   ,
    input                        rst_n     ,
    input                        iic_end   ,
    input                        key_flag_1 ,
    input                        key_flag_2 ,
    (* MARK_DEBUG="true" *)output        reg            wr_en     ,
    (* MARK_DEBUG="true" *)output        reg            rd_en     ,
    (* MARK_DEBUG="true" *)output        reg            iic_start  //按键消抖后延迟1000个时钟周期
    );
    
    always@(posedge sys_clk )
         if(!rst_n)
            wr_en <= 0 ;
         else if ( key_flag_1 )
            wr_en <= 1 ;
         else if ( iic_end )
            wr_en <= 0 ;
         else
            wr_en <= wr_en ;
    
    always@(posedge sys_clk )
         if(!rst_n)
            rd_en <= 0 ;
         else if ( key_flag_2 )
            rd_en <= 1 ;
         else if ( iic_end )
            rd_en <= 0 ;
         else
            rd_en <= rd_en ; 
  
  ///cnt
  parameter              TIME_COUNT = 10'd1000 ;
   (* MARK_DEBUG="true" *)reg[9:0]                cnt  ;
    
     always@(posedge sys_clk )
          if(!rst_n )
             cnt <= 0 ;
          else if ( wr_en || rd_en )begin
               if ( cnt == TIME_COUNT -1 )
                    cnt <= cnt ;
               else
                    cnt <= cnt +1 ;
          end
          else
          cnt <= 0 ;
    
    iic_start
      always@(posedge sys_clk )
           if(!rst_n)
              iic_start <= 0 ;
           else if ( cnt == TIME_COUNT -2 )
              iic_start <= 1 ;
           else
              iic_start <= 0 ;      

endmodule

(3)IIC模块

`timescale 1ns / 1ps
module IIC_2
#(
    parameter       SYSCLK    = 50_000_000         ,
                     IIC_CLK   = 400_000           ,
                     DEVICE_ID = 7'b1010_000
)
(
    input                   sysclk              ,
    input                   rst_n               ,
    input   [7:0]           data_in             ,
    input   [7:0]           addr                ,
       input                   iic_start           ,   尖峰脉冲
       input                   wr_en               ,   ///按键1按下触发
       input                   rd_en               ,   ///按键2按下触发
       (* MARK_DEBUG="true" *)output                  tx_start            ,
       (* MARK_DEBUG="true" *)output  reg     [7:0]   rd_data             ,
       (* MARK_DEBUG="true" *)output  reg             SCL                 ,
       (* MARK_DEBUG="true" *)inout                   SDA                 ,
       (* MARK_DEBUG="true" *)output                  iic_end                 /尖峰脉冲
    );
localparam          DELAY = SYSCLK/IIC_CLK          ;
//三态门
wire        sda_en          ;  ///SDA先作为输出时候的使能信号线
wire        sda_in          ;  从机给主机的数据线
reg         sda_out         ;  /主机给从机的数据线
assign      SDA = (sda_en == 1) ? sda_out : 1'bz        ;
assign      sda_in  =  SDA;
状态机
localparam          IDLE          = 4'd0     ,
                    START1        = 4'd1     ,
                    SEND_DEVICE_W = 4'd2     ,
                    ACK1          = 4'd3     ,
                    SEND_ADDR_W   = 4'd4     ,
                    ACK2          = 4'd5     ,
                    SEND_DATA_W   = 4'd6     ,
                    ACK3          = 4'd7     ,
                    STOP          = 4'd8     ,
                                             
                    START2        = 4'd9     ,
                    SEND_DEVICE_R = 4'd10    ,
                    ACK4          = 4'd11    ,
                    READ_DATA     = 4'd12    ,
                    NOACK         = 4'd13    ;                 
(* MARK_DEBUG="true" *)reg     [3:0]       cur_state       ;
reg     [3:0]       next_state       ;
 (* MARK_DEBUG="true" *)reg     [7:0]       cnt             ;
 (* MARK_DEBUG="true" *)reg     [2:0]       cnt_bit         ;
 (* MARK_DEBUG="true" *)reg                 ack_flag        ;
assign      sda_en = (cur_state == ACK1 || cur_state == ACK2 ||
                      cur_state == ACK3 || cur_state == ACK4 || cur_state == READ_DATA) ? 0 : 1;
assign      tx_start = (cur_state == READ_DATA && cnt_bit == 7 && cnt == DELAY - 1) ? 1 : 0;
assign      iic_end  = (cur_state == STOP && cnt == DELAY - 1) ? 1 : 0; 
/state1
always@(posedge sysclk)
    if(!rst_n)
        cur_state <= IDLE;
    else
        cur_state <= next_state;
/state2
always@(*)   
    case(cur_state)
        IDLE          : begin
            if(iic_start == 1)
                next_state = START1;
            else
                next_state = cur_state;
        end  
        START1        :begin
            if(cnt == DELAY - 1)
                next_state = SEND_DEVICE_W;
            else
                next_state = cur_state;
        end
        SEND_DEVICE_W :begin
            if(cnt == DELAY - 1 && cnt_bit == 7)
                next_state = ACK1;
            else
                next_state = cur_state;
        end
        ACK1          :begin
            if(cnt == DELAY - 1 && ack_flag == 0)   /应答有效
                next_state = SEND_ADDR_W;
            else if(cnt == DELAY - 1 && ack_flag == 1)   /应答无效
                next_state = IDLE;
            else
                next_state = cur_state;
        end
        SEND_ADDR_W   :begin
            if(cnt == DELAY - 1 && cnt_bit == 7)
                next_state = ACK2;
            else
                next_state = cur_state;
        end
        ACK2          :begin
            if(cnt == DELAY - 1 && ack_flag == 0 && wr_en)   /应答有效
                next_state = SEND_DATA_W;
            else if(cnt == DELAY - 1 && ack_flag == 0 && rd_en)   /应答有效
                next_state = START2;
            else if(cnt == DELAY - 1 && ack_flag == 1)   /应答无效
                next_state = IDLE;
            else
                next_state = cur_state;
        end
        SEND_DATA_W   :begin
            if(cnt == DELAY - 1 && cnt_bit == 7)
                next_state = ACK3;
            else
                next_state = cur_state;
        end
        ACK3          :begin
            if(cnt == DELAY - 1 && ack_flag == 0)   /应答有效
                next_state = STOP;
            else if(cnt == DELAY - 1 && ack_flag == 1)   /应答无效
                next_state = IDLE;
            else
                next_state = cur_state;
        end
        STOP          :begin
            if(cnt == DELAY - 1)
                next_state = IDLE;
            else
                next_state = cur_state;
        end
        START2        : begin
            if(cnt == DELAY - 1)
                next_state = SEND_DEVICE_R;
            else
                next_state = cur_state;
        end
        SEND_DEVICE_R :begin
            if(cnt == DELAY - 1 && cnt_bit == 7)
                next_state = ACK4;
            else
                next_state = cur_state;
        end
        ACK4          :begin
            if(cnt == DELAY - 1 && ack_flag == 0)   /应答有效
                next_state = READ_DATA;
            else if(cnt == DELAY - 1 && ack_flag == 1)   /应答无效
                next_state = IDLE;
            else
                next_state = cur_state;
        end
        READ_DATA     :begin
            if(cnt == DELAY - 1 && cnt_bit == 7)
                next_state = NOACK;
            else
                next_state = cur_state;
        end
        NOACK         :begin
            if(cnt == DELAY - 1)
                next_state = STOP;
            else
                next_state = cur_state;
        end
        default:next_state = IDLE;  
    endcase
state3
always@(posedge sysclk)
    if(!rst_n)begin
        cnt <= 0;
        cnt_bit <= 0;
        sda_out <= 1;  空闲为1
        SCL <= 1;空闲为1
        ack_flag <= 1;  无效应答
        rd_data <= 0;
    end
    else
        case(cur_state)
            IDLE          :begin
                rd_data <= 0;
                cnt <= 0;
                cnt_bit <= 0;
                sda_out <= 1; 
                SCL <= 1;
                ack_flag <= 1;
            end    
            START1        :begin
                ack_flag <= 1;
                if(cnt >= DELAY*3/4 - 1)
                    SCL <= 0;
                else
                    SCL <= 1;
                if(cnt >= DELAY/2 - 1)
                    sda_out <= 0;
                else
                    sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            SEND_DEVICE_W :begin   先发最高位  0-7  0-6  7
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                if(cnt_bit >=0 && cnt_bit < 7)
                    sda_out <= DEVICE_ID[6-cnt_bit];
                else    /cnt_bit == 7
                    sda_out <= 0;   //写标志位
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
                if(cnt == DELAY - 1)
                    cnt_bit <= cnt_bit + 1;
                else
                    cnt_bit <= cnt_bit;
            end
            ACK1          :begin   /从机给主机数据
                if(cnt == DELAY/2 - 1)
                    ack_flag <= sda_in  ;
                else
                    ack_flag <= ack_flag;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            SEND_ADDR_W   :begin
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= addr[7-cnt_bit];
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
                if(cnt == DELAY - 1)
                    cnt_bit <= cnt_bit + 1;
                else
                    cnt_bit <= cnt_bit;
            end
            ACK2          :begin
                if(cnt == DELAY/2 - 1)
                    ack_flag <= sda_in  ;
                else
                    ack_flag <= ack_flag;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            SEND_DATA_W   :begin
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= data_in[7-cnt_bit];
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
                if(cnt == DELAY - 1)
                    cnt_bit <= cnt_bit + 1;
                else
                    cnt_bit <= cnt_bit;
            end
            ACK3          :begin
                if(cnt == DELAY/2 - 1)
                    ack_flag <= sda_in  ;
                else
                    ack_flag <= ack_flag;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            STOP          :begin
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                if(cnt >= DELAY/2 - 1)
                    sda_out <= 1;
                else
                    sda_out <= 0;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
                          
            START2        :begin
                ack_flag <= 1;
                if(cnt >= DELAY*3/4 - 1)
                    SCL <= 0;
                else
                    SCL <= 1;
                if(cnt >= DELAY/2 - 1)
                    sda_out <= 0;
                else
                    sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            SEND_DEVICE_R :begin
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                if(cnt_bit >=0 && cnt_bit < 7)
                    sda_out <= DEVICE_ID[6-cnt_bit];
                else    /cnt_bit == 7
                    sda_out <= 1;   //读标志位
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
                if(cnt == DELAY - 1)
                    cnt_bit <= cnt_bit + 1;
                else
                    cnt_bit <= cnt_bit;
            end
            ACK4          :begin
                if(cnt == DELAY/2 - 1)
                    ack_flag <= sda_in  ;
                else
                    ack_flag <= ack_flag;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end
            READ_DATA     :begin
                if(cnt == DELAY/2 - 1)
//                    rd_data[7-cnt_bit] <= sda_in;  /法1
                    rd_data <= {rd_data[6:0],sda_in};  法2
                else
                    rd_data <= rd_data;
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
                if(cnt == DELAY - 1)
                    cnt_bit <= cnt_bit + 1;
                else
                    cnt_bit <= cnt_bit;
            end
            NOACK         :begin
                ack_flag <= 1;
                if(cnt >= DELAY/4 - 1 && cnt <= DELAY*3/4 - 1)
                    SCL <= 1;
                else
                    SCL <= 0;
                sda_out <= 1;
                cnt_bit <= 0;
                if(cnt == DELAY - 1)
                    cnt <= 0;
                else
                    cnt <= cnt + 1;
            end 
        endcase
endmodule

(4)发送端模块

`timescale 1ns / 1ps
module uart_tx(
    input                 sys_clk   ,
    input                 rst_n     ,
    input                 tx_start  ,
      (* MARK_DEBUG="true" *) input     [7:0]       rd_data   ,
      (* MARK_DEBUG="true" *)output    reg         tx_data   ,
    output    reg         tx_done
    );
    parameter            SYSCLK = 50_000_000 ;
    parameter            Baud   = 115200     ;
    parameter            COUNT  = SYSCLK/Baud;
    parameter            MID    = COUNT/2    ;
    

    
    //start_flag
    reg              tx_reg1 ;
    reg              tx_reg2 ;
    (* MARK_DEBUG="true" *)wire             start_flag ;
    
    always@(posedge sys_clk )
         if(!rst_n)begin
            tx_reg1 <= 0 ;
            tx_reg2 <= 0 ;
         end
         else
             begin
                  tx_reg1 <= tx_start ;
                  tx_reg2 <= tx_reg1  ;
             end
   assign start_flag = tx_reg1 & ~tx_reg2 ;
   
   //tx_flag
  (* MARK_DEBUG="true" *) reg              tx_flag  ;
  (* MARK_DEBUG="true" *) reg [9:0]        cnt      ;
  (* MARK_DEBUG="true" *) reg [4:0]        cnt_bit  ; //0 12345678 9 10 
   
   always@(posedge sys_clk )
        if(!rst_n)
           tx_flag <= 0 ;
        else if ( start_flag )
           tx_flag <= 1 ;
        else if ( cnt == COUNT -1 && cnt_bit == 10 )
           tx_flag <= 0 ;
        else
           tx_flag <= tx_flag ;
   
   //cnt
   always@(posedge sys_clk )
        if(!rst_n)
           cnt <= 0 ;
        else if ( tx_flag )begin
             if ( cnt == COUNT -1 )
                  cnt <= 0 ;
             else
                  cnt <= cnt +1 ;
        end
        else
        cnt <= 0 ;
   
   //cnt_bit 
     always@(posedge sys_clk )
          if(!rst_n)
             cnt_bit <= 0 ;
          else if ( tx_flag )begin
               if ( cnt == COUNT -1 )begin
                   if ( cnt_bit == 10 )
                        cnt_bit <= 0 ;
                   else
                        cnt_bit <= cnt_bit +1 ;
               end
               else
               cnt_bit <= cnt_bit ;
          end
          else
          cnt_bit <= 0 ;
   
   
       //寄存rd_data     rd_data随着cur_state变为STOP后清零,在uart_tx模块
    //中,cnt_bit == 0 的时候可以捕捉到数据
   (* MARK_DEBUG="true" *) reg[7:0]              data_reg  ;
    always@(posedge sys_clk )
         if(!rst_n)
            data_reg <= 0 ;
         else if ( tx_flag )begin
              if ( cnt_bit == 0 && cnt == MID -1 )
                  data_reg <= rd_data ;
              else
                  data_reg <= data_reg ;
         end
         else
         data_reg <= data_reg ;
   
     
   
   //tx_data
   parameter                  MODE_CHECK = 0 ;
   always@(posedge sys_clk )
        if(!rst_n)                  //cnt_bit: 0 12345678 9 10
            tx_data <= 0 ;          //rd_data: 01234567
        else if ( tx_flag )begin
             if ( cnt_bit > 0 && cnt_bit <9 )
                  tx_data <= data_reg [ cnt_bit -1 ] ;
             else if ( cnt_bit == 0 )
                  tx_data <= 0 ;
             else if ( cnt_bit == 10 )
                  tx_data <= 1 ;
             else if ( cnt_bit == 9 )
                  tx_data <= (MODE_CHECK == 0 )? ^rd_data : ~^rd_data ;
             else
                  tx_data <= tx_data ;                
        end
        else
        tx_data <= 1 ;
    
    //tx_done 
    always@(posedge sys_clk )
         if(!rst_n)
            tx_done <= 0 ;
         else if ( tx_flag )begin
              if ( cnt == COUNT -1 && cnt_bit == 10 )
                   tx_done <= 1 ;
              else
                   tx_done <= 0 ;
         end
         else
         tx_done <= 0 ;
            
   
   
   
            
    
    
    
    
endmodule

(5)TOP模块

`timescale 1ns / 1ps
module IIC_TOP(
   input                  sys_clk   ,
   input                  rst_n     ,
   input                  key1      ,
   input                  key2      ,
   output                 tx_data   ,
   output                 SCL       ,
   inout                  SDA
    );
  key
  wire                   key_flag_1 ;
  wire                   key_flag_2 ;
    key  key_u1(
               .    sys_clk     (sys_clk    )   ,
               .    rst_n       (rst_n      )   ,
               .    key1        (key1       )   ,
               .    key2        (key2       )   ,
               .    key_flag_1  (key_flag_1 )   ,
               .    key_flag_2  (key_flag_2 )
     
    );
 
 ///data_generate
    wire               iic_end    ;
    wire               wr_en      ;
    wire               rd_en      ;
    wire               iic_start  ;
 
    data_generate data_generate_u1(
                   .    sys_clk     (sys_clk   )  ,
                   .    rst_n       (rst_n     )  ,
                   .    iic_end     (iic_end   )  ,
                   .    key_flag_1  (key_flag_1)  ,
                   .    key_flag_2  (key_flag_2)  ,
                   .    wr_en       (wr_en     )  ,
                   .    rd_en       (rd_en     )  ,
                   .    iic_start   (iic_start )    //按键消抖后延迟1000个时钟周期
    );
    
    IIC
   wire              tx_start   ;
   wire      [7:0]   rd_data    ;
    IIC_2
    #(
              .   SYSCLK     (50_000_000 )        ,
              .   IIC_CLK    (400_000    )        ,
              .   DEVICE_ID  (7'b1010_000)
    )
    IIC_2_u1(
              .     sysclk      (sys_clk)        ,
              .     rst_n       (rst_n )        ,
              .     data_in     (8'h45)        ,
              .     addr        (8'h12)        ,
              .     iic_start   (iic_start)        ,   尖峰脉冲
              .     wr_en       (wr_en   )        ,   ///按键1按下触发
              .     rd_en       (rd_en   )        ,   ///按键2按下触发
              .     tx_start    (tx_start)        ,
              .     rd_data     (rd_data )        ,
              .     SCL         (SCL     )        ,
              .     SDA         (SDA     )        ,
              .     iic_end     (iic_end )            /尖峰脉冲
        );
 
 ///uart_tx
 wire               tx_done    ;
 uart_tx uart_tx_u1(
              .     sys_clk   (sys_clk )  ,
              .     rst_n     (rst_n   )  ,
              .     tx_start  (tx_start)  ,
              .     rd_data   (rd_data )  ,
              .     tx_data   (tx_data )  ,
              .     tx_done   (tx_done )
    );
 
 
 

    
    
    
endmodule

(6)绑定管脚

set_property IOSTANDARD LVCMOS33 [get_ports key1]
set_property IOSTANDARD LVCMOS33 [get_ports key2]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports SCL]
set_property IOSTANDARD LVCMOS33 [get_ports SDA]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports tx_data]
set_property PACKAGE_PIN M19 [get_ports key1]
set_property PACKAGE_PIN M20 [get_ports key2]
set_property PACKAGE_PIN P15 [get_ports rst_n]
set_property PACKAGE_PIN F19 [get_ports SCL]
set_property PACKAGE_PIN F20 [get_ports SDA]
set_property PACKAGE_PIN K17 [get_ports sys_clk]
set_property PACKAGE_PIN U18 [get_ports tx_data]

四、set up debug使用步骤

然后点set up debug

XDC文件变成这样就是保存成功了

set_property IOSTANDARD LVCMOS33 [get_ports key1]
set_property IOSTANDARD LVCMOS33 [get_ports key2]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports SCL]
set_property IOSTANDARD LVCMOS33 [get_ports SDA]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports tx_data]
set_property PACKAGE_PIN M19 [get_ports key1]
set_property PACKAGE_PIN M20 [get_ports key2]
set_property PACKAGE_PIN P15 [get_ports rst_n]
set_property PACKAGE_PIN F19 [get_ports SCL]
set_property PACKAGE_PIN F20 [get_ports SDA]
set_property PACKAGE_PIN K17 [get_ports sys_clk]
set_property PACKAGE_PIN U18 [get_ports tx_data]


create_debug_core u_ila_0 ila
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
set_property C_DATA_DEPTH 4096 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
set_property port_width 1 [get_debug_ports u_ila_0/clk]
connect_debug_port u_ila_0/clk [get_nets [list sys_clk_IBUF_BUFG]]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
set_property port_width 8 [get_debug_ports u_ila_0/probe0]
connect_debug_port u_ila_0/probe0 [get_nets [list {IIC_2_u1/cnt[0]} {IIC_2_u1/cnt[1]} {IIC_2_u1/cnt[2]} {IIC_2_u1/cnt[3]} {IIC_2_u1/cnt[4]} {IIC_2_u1/cnt[5]} {IIC_2_u1/cnt[6]} {IIC_2_u1/cnt[7]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1]
set_property port_width 3 [get_debug_ports u_ila_0/probe1]
connect_debug_port u_ila_0/probe1 [get_nets [list {IIC_2_u1/cnt_bit[0]} {IIC_2_u1/cnt_bit[1]} {IIC_2_u1/cnt_bit[2]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2]
set_property port_width 4 [get_debug_ports u_ila_0/probe2]
connect_debug_port u_ila_0/probe2 [get_nets [list {IIC_2_u1/cur_state[0]} {IIC_2_u1/cur_state[1]} {IIC_2_u1/cur_state[2]} {IIC_2_u1/cur_state[3]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3]
set_property port_width 10 [get_debug_ports u_ila_0/probe3]
connect_debug_port u_ila_0/probe3 [get_nets [list {data_generate_u1/cnt[0]} {data_generate_u1/cnt[1]} {data_generate_u1/cnt[2]} {data_generate_u1/cnt[3]} {data_generate_u1/cnt[4]} {data_generate_u1/cnt[5]} {data_generate_u1/cnt[6]} {data_generate_u1/cnt[7]} {data_generate_u1/cnt[8]} {data_generate_u1/cnt[9]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4]
set_property port_width 8 [get_debug_ports u_ila_0/probe4]
connect_debug_port u_ila_0/probe4 [get_nets [list {uart_tx_u1/rd_data[0]} {uart_tx_u1/rd_data[1]} {uart_tx_u1/rd_data[2]} {uart_tx_u1/rd_data[3]} {uart_tx_u1/rd_data[4]} {uart_tx_u1/rd_data[5]} {uart_tx_u1/rd_data[6]} {uart_tx_u1/rd_data[7]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5]
set_property port_width 8 [get_debug_ports u_ila_0/probe5]
connect_debug_port u_ila_0/probe5 [get_nets [list {IIC_2_u1/rd_data[0]} {IIC_2_u1/rd_data[1]} {IIC_2_u1/rd_data[2]} {IIC_2_u1/rd_data[3]} {IIC_2_u1/rd_data[4]} {IIC_2_u1/rd_data[5]} {IIC_2_u1/rd_data[6]} {IIC_2_u1/rd_data[7]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6]
set_property port_width 1 [get_debug_ports u_ila_0/probe6]
connect_debug_port u_ila_0/probe6 [get_nets [list IIC_2_u1/ack_flag]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7]
set_property port_width 1 [get_debug_ports u_ila_0/probe7]
connect_debug_port u_ila_0/probe7 [get_nets [list IIC_2_u1/iic_end]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8]
set_property port_width 1 [get_debug_ports u_ila_0/probe8]
connect_debug_port u_ila_0/probe8 [get_nets [list data_generate_u1/iic_start]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9]
set_property port_width 1 [get_debug_ports u_ila_0/probe9]
connect_debug_port u_ila_0/probe9 [get_nets [list key_u1/key1]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10]
set_property port_width 1 [get_debug_ports u_ila_0/probe10]
connect_debug_port u_ila_0/probe10 [get_nets [list key_u1/key2]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11]
set_property port_width 1 [get_debug_ports u_ila_0/probe11]
connect_debug_port u_ila_0/probe11 [get_nets [list key_u1/key_flag_1]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12]
set_property port_width 1 [get_debug_ports u_ila_0/probe12]
connect_debug_port u_ila_0/probe12 [get_nets [list key_u1/key_flag_2]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13]
set_property port_width 1 [get_debug_ports u_ila_0/probe13]
connect_debug_port u_ila_0/probe13 [get_nets [list data_generate_u1/rd_en]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe14]
set_property port_width 1 [get_debug_ports u_ila_0/probe14]
connect_debug_port u_ila_0/probe14 [get_nets [list IIC_2_u1/SCL]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe15]
set_property port_width 1 [get_debug_ports u_ila_0/probe15]
connect_debug_port u_ila_0/probe15 [get_nets [list IIC_2_u1/SDA_IBUF]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe16]
set_property port_width 1 [get_debug_ports u_ila_0/probe16]
connect_debug_port u_ila_0/probe16 [get_nets [list IIC_2_u1/SDA_OBUF]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe17]
set_property port_width 1 [get_debug_ports u_ila_0/probe17]
connect_debug_port u_ila_0/probe17 [get_nets [list uart_tx_u1/tx_data]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe18]
set_property port_width 1 [get_debug_ports u_ila_0/probe18]
connect_debug_port u_ila_0/probe18 [get_nets [list IIC_2_u1/tx_start]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe19]
set_property port_width 1 [get_debug_ports u_ila_0/probe19]
connect_debug_port u_ila_0/probe19 [get_nets [list data_generate_u1/wr_en]]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets sys_clk_IBUF_BUFG]

"4"对应后面几个cnt_bit

五、实验结果

按下控制“写”的按键,再按下“读”的按键后,pc端返回45

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FPGA读写EEPROM芯片AT24C02实验Verilog逻辑源码Quartus11.0工程文件, FPGA型号为CYCLONE4E系列中的EP4CE6E22C8,可以做为你的学习设计参考。 module iic_com( clk,rst_n, sw1,sw2, scl,sda, dis_data ); input clk; // 50MHz input rst_n; //复位信号,低有效 input sw1,sw2; //按键1、2,(1按下执行写入操作,2按下执行读操作) output scl; // 24C02的时钟端口 inout sda; // 24C02的数据端口 output[7:0] dis_data; //数码管显示数据 //按键检测 reg sw1_r,sw2_r; //键值锁存寄存器,每20ms检测一次键值 reg[19:0] cnt_20ms; //20ms计数寄存器 always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt_20ms <= 20'd0; else cnt_20ms <= cnt_20ms+1'b1; //不断计数 end always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin sw1_r <= 1'b1; //键值寄存器复位,没有键盘按下时键值都为1 sw2_r <= 1'b1; end else if(cnt_20ms == 20'hfffff) begin sw1_r <= sw1; //按键1值锁存 sw2_r <= sw2; //按键2值锁存 end end //--------------------------------------------- //分频部分 reg[2:0] cnt; // cnt=0:scl上升沿,cnt=1:scl高电平中间,cnt=2:scl下降沿,cnt=3:scl低电平中间 reg[8:0] cnt_delay; //500循环计数,产生iic所需要的时钟 reg scl_r; //时钟脉冲寄存器 always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt_delay <= 9'd0; else if(cnt_delay == 9'd499) cnt_delay <= 9'd0; //计数到10us为scl的周期,即100KHz else cnt_delay <= cnt_delay+1'b1; //时钟计数 end always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt <= 3'd5; else begin case (cnt_delay) 9'd124: cnt <= 3'd1; //cnt=1:scl高电平中间,用于数据采样 9'd249: cnt <= 3'd2; //cnt=2:scl下降沿 9'd374: cnt <= 3'd3; //cnt=3:scl低电平中间,用于数据变化 9'd499: cnt <= 3'd0; //cnt=0:scl上升沿 default: cnt <= 3'd5; endcase end end `define SCL_POS (cnt==3'd0) //cnt=0:scl上升沿 `define SCL_HIG (cnt==3'd1) //cnt=1:scl高电平中间,用于数据采样 `define SCL_NEG (cnt==3'd2) //cnt=2:scl下降沿 `define SCL_LOW (cnt==3'd3) //cnt=3:scl低电平中间,用于数据变化 always @ (posedge clk or negedge rst_n) begin if(!rst_n) scl_r <= 1'b0; else if(cnt==3'd0) scl_r <= 1'b1; //scl信号上升沿
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值