• Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)


    利用状态机实现比较复杂的接口设计:

    这是一个将并行数据转换为串行输出的变换器,利用双向总线输出。这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍:

    I2C总线(inter integrated circuit)双向二线制串行总线协议为:只有总线处于“非忙”状态时,数据传输才开始。在数据传输期间,只要时钟线为高电平,数据线都必须保持稳定,否则数据线上的任何变化都被当作“启动”或“停止”信号。

    下面介绍A、B、C、D的工作状态:

    (1)总线处于非忙状态(A段):该段内的数据线(sda)和时钟线(scl)都保持高电平;

    (2)启动数据传输(B段):当时钟线(scl)为高电平时,数据线(sda)由高电平变为低电平的下降沿被认为是“启动”信号;

    (3)停止数据传输(C段):当时钟线(scl)为高电平时,数据线(sda)由低电平变为高电平的上升沿被认为是“停止”信号;

    (4)数据有效(D段):在出现“启动”信号之后,在时钟线(scl)为高电平时,数据线是稳定的,这是数据线上的数据就是要传送的数据,数据线上的数据改变必须在时钟线(scl)为低电平期间完成,每个数据占用一个时钟;

    (5)应答信号:每个正在接受数据的EEPROM在接收到一个字节的数据后,通常需要发出一个应答信号;而每个正在发送数据的EEPROM在发出一个字节的数据后,通常需要接受一个应答信号;EEPROM读写控制器必须提供一个与这个应答信号相联系的二外的始终脉冲。

    其控制字节一共有8位:1010xxxW/R 其中1010是I2C总线器件特征编码,xxx表示地址,W/R表示读写状态。

     

    在实现并行输入串行输出时,需要两个状态机:

    主状态机主要控制内部存储器和输入端的连接,以及给出应答信号;从状态机主要负责总线连接时,内部寄存器的最高位输出个移位;

    状态机的源码如下:

      1 module parallel_to_serial(rst,clk,addr,data,sda,ack);
      2   input rst,clk;
      3   input [7:0]data,addr;
      4   
      5   inout sda;                     //data bus
      6   output ack;                    //ask for next address/data writting wo eeprm;
      7   reg link_write;                //whether connect to output
      8   reg [2:0]state;                //main status,
      9   reg [4:0]sh8out_state;         //serial output status
     10   reg [7:0]sh8out_buf;           //output data buffer
     11   reg finish_F;                  //whether finished an operation of main status
     12   reg ack;                       
     13   
     14   parameter  idle=0, addr_write=3'd1, data_write=3'd2, stop_ack=3'd4;          //main status code
     15   parameter  bit0=1, bit1=2, bit2=3, bit3=4, bit4=5, bit5=6, bit6=7, bit7=8;   //serial output status code
     16   
     17   assign sda=link_write?sh8out_buf[7]:1'bz;               //???????????
     18   
     19   always @(posedge clk)
     20   begin
     21   if(!rst)                       //reset
     22     begin
     23     ack<=0;
     24     link_write<=0;               //???????
     25     finish_F<=0;
     26     state<=idle;
     27     sh8out_state<=idle;
     28     sh8out_buf<=0;
     29     end
     30     else
     31       case(state)
     32         idle:begin
     33              link_write<=0;        //??????
     34              ack<=0;
     35              finish_F<=0;
     36              sh8out_buf<=addr;     //???????
     37              sh8out_state<=idle;
     38              state<=addr_write;    //???????
     39              end
     40         addr_write:begin
     41              if (finish_F==0) begin shift8_out;end    //???????
     42              else
     43                begin
     44                link_write<=0;
     45                ack<=0;
     46                finish_F<=0;
     47                sh8out_buf<=data;  //???????
     48                state<=data_write;
     49                sh8out_state<=idle;     
     50                end          
     51              end
     52         data_write:begin
     53              if (finish_F==0) begin shift8_out;end    //???????
     54              else
     55                begin
     56                link_write<=0;
     57                finish_F<=0;
     58                state<=stop_ack;
     59                ack<=1;            //????????
     60                end
     61              end 
     62         stop_ack:begin            //????
     63              ack<=0;
     64              state<=idle;
     65              end    
     66       endcase
     67     end
     68     
     69     task shift8_out;             //???????
     70     begin
     71     case(sh8out_state)
     72       idle:begin
     73            link_write<=1;        //?????????????????17?assign sda=link_write?sh8out_buf[7]:1'bz;  sda??????????sh8out_buf?????  
     74            sh8out_state<=bit7;
     75            end
     76       bit7:begin
     77            link_write<=1;       
     78            sh8out_buf=sh8out_buf<<1;   //?????data?????bit6
     79            sh8out_state<=bit6;
     80            end
     81       bit6:begin
     82            link_write<=1;       
     83            sh8out_buf=sh8out_buf<<1;  
     84            sh8out_state<=bit5;
     85            end
     86       bit5:begin
     87            link_write<=1;       
     88            sh8out_buf=sh8out_buf<<1;   
     89            sh8out_state<=bit4;
     90            end
     91       bit4:begin
     92            link_write<=1;       
     93            sh8out_buf=sh8out_buf<<1;   
     94            sh8out_state<=bit3;
     95            end
     96       bit3:begin
     97            link_write<=1;       
     98            sh8out_buf=sh8out_buf<<1;   
     99            sh8out_state<=bit2;
    100            end
    101       bit2:begin
    102            link_write<=1;       
    103            sh8out_buf=sh8out_buf<<1;   
    104            sh8out_state<=bit1;
    105            end
    106       bit1:begin
    107            link_write<=1;       
    108            sh8out_buf=sh8out_buf<<1;   
    109            sh8out_state<=bit0;
    110            end
    111       bit0:begin
    112            link_write<=0;       
    113            finish_F<=1;
    114            end
    115       endcase
    116     end
    117     endtask
    118 endmodule

     测试程序:

     1 `timescale 1ns/1ns
     2 `define clk_period 50
     3 module parallel_to_serial_test;
     4   reg rst,clk;
     5   reg [7:0]data,addr;
     6   wire ack,sda;
     7   wire [2:0]state;                //main status,
     8   wire [4:0]sh8out_state; 
     9   
    10   initial 
    11   begin
    12   clk=0;
    13   rst=1;
    14   data=0;
    15   addr=0;
    16   #(2*`clk_period) rst=0;
    17   #(2*`clk_period) rst=1;
    18   #(100*`clk_period) $stop;
    19   end
    20   
    21   always #50 clk=~clk;
    22   
    23   
    24 
    25   always @(posedge clk)
    26   begin data=data+1; addr=addr+1; end
    27   
    28   parallel_to_serial m(
    29                        .rst(rst),
    30                        .clk(clk),
    31                        .addr(addr),
    32                        .data(data),
    33                        .sda(sda),
    34                        .ack(ack)
    35   );
    36   
    37   assign state=m.state;
    38   assign sh8out_state=m.sh8out_state; 
    39 endmodule

    波形信号:

  • 相关阅读:
    Java抽象类和接口和继承之间关系
    Java程序中解决数据库超时与死锁
    怎样成为一名出色的Java Web程序员?
    Java中断线程的方法
    Java 集合框架(Collection)和数组的排序
    StringBuffer帮你减轻Java的负担
    学好Java开发的关键七步
    kvm的分层控制
    一个高扩展高可用高负载的应用架构的诞生记(原创)
    防火墙规则
  • 原文地址:https://www.cnblogs.com/SYoong/p/6066825.html
Copyright © 2020-2023  润新知