zoukankan      html  css  js  c++  java
  • 较复杂时序逻辑电路设计实践一

    1、功能图

        M0发送数据给M1,M1存取数据并赋给串行的sda,传给M0。

    2、时序图

     

      由时序图可以看出:说重点就是,这句最重点,理解哈,如果scl=1,那么sda由高变低时刻串行数据流开始;如果scl=1,那么sda由低变高时刻串行数据流结束,如果scl=0,那么我们的sda数据就可以变化了。

    3、状态图

      这是描述的时序状态图,我们可以看出,状态图就只是状态,这是时序的状态,注意clk的行为。从状态转换的条件来看,转换成功的关键在于看懂时序图,即:什么条件是代表开始,什么条件代表存数据??

    4、M1程序

      1 //M1程序
      2 module ptosda(rst,sclk,ack,scl,sda,data);
      3 
      4 input sclk,rst;//外部时钟和复位
      5 input[3:0] data;//外部数据
      6 output ack;//请求
      7 output scl;//m1的时钟
      8 output sda;//M1数据线
      9 
     10 reg scl,link_sda,ack,sdabuf;//总线开光,数据串行寄存变量
     11 reg[3:0]databuf;//M1内部数据寄存
     12 reg[7:0]state;//状态变量
     13 
     14 //九种状态,怎么想的呢???
     15 parameter     ready=8'b0000_0000,//等待
     16             start=8'b0000_0001,//开始
     17             bit1=8'b0000_0010,//数据1
     18             bit2=8'b0000_0100,//数据2
     19             bit3=8'b0000_1000,//数据3
     20             bit4=8'b0001_0000,//数据4
     21             bit5=8'b0010_0000,//数据5
     22             stop=8'b0100_0000,//结束
     23             idle=8'b1000_0000;//空闲
     24 
     25 always@(posedge sclk or negedge rst)//先把时钟设置好,就是这样设置的
     26     begin
     27         if(!rst)
     28             scl<=1;//m1的scl时钟需要先是高位
     29         else
     30             scl<=~scl;//这里的数据是sclk的周期的二倍,把sclk的时钟信号传递给了scl,一种方法,5rf你懂的
     31     end
     32     
     33 always@(posedge ack)//再把数据接受好
     34     databuf<=data;//只要请求到来,就会把数据传给databuf
     35     
     36 //------主状态机:产生控制信号,根据databuf中的保存数据,按照协议产生sda串行信号
     37 always@(negedge sclk or negedge rst)//这里是sclk 没有用scl用低电平触发
     38     if(!rst)
     39         begin
     40             link_sda<=0;//断开总线
     41             state<=ready;//进入准备状态
     42             sdabuf<=1;//m1传输数据总线打开
     43             ack<=0;//请求置0    
     44         end
     45     else
     46         begin
     47             case(state)
     48                 ready:
     49                     if(ack)//
     50                         begin
     51                             link_sda<=1;//sda的总线打开
     52                             state<=start;//进入另外的开始阶段
     53                         end
     54                     else    
     55                         begin
     56                             link_sda<=0;//sda 总线关闭
     57                             state<=ready;
     58                             ack<=1;//请求数据
     59                         end
     60                 start:
     61                     if(scl&&ack)//scl是高电平传状态,低电平传数据
     62                         begin
     63                             sdabuf<=0;//sdabuf寄存0
     64                             state<=bit1;//进入bit1状态
     65                         end
     66                     else
     67                         state<=start;//等待scl高电平到来
     68                 bit1:
     69                     if(!scl)
     70                         begin
     71                             sdabuf<=databuf[3];//sdabuf寄存高位数据
     72                             state<=bit2;//进入bit2状态
     73                             ack<=0;//关闭请求
     74                         end
     75                     else
     76                         state<=bit1;//等待scl变低电平,似乎是
     77                 bit2:
     78                     if(!scl)
     79                         begin
     80                             sdabuf<=databuf[2];
     81                             state<=bit3;
     82                         end
     83                     else
     84                         state<=bit2;
     85                 bit3:
     86                     if(!scl)
     87                         begin
     88                             sdabuf<=databuf[1];
     89                             state<=bit4;
     90                         end
     91                     else
     92                         state<=bit3;
     93                 bit4:
     94                     if(!scl)
     95                         begin
     96                             sdabuf<=databuf[0];
     97                             state<=bit5;
     98                         end
     99                     else
    100                         state<=bit4;
    101                 
    102                 bit5:
    103                     if(!scl)
    104                         begin
    105                             sdabuf<=0;
    106                             state<=stop;
    107                         end
    108                     else
    109                         state<=bit5;
    110                 stop:
    111                     if(scl)
    112                         begin
    113                             sdabuf<=1;
    114                             state<=idle;
    115                         end
    116                     else
    117                         state<=stop;
    118                 idle:
    119                     begin
    120                         link_sda<=0;
    121                         state<=ready;
    122                     end
    123                 default:
    124                     begin
    125                         link_sda<=0;
    126                         state<=1;
    127                         state<=ready;
    128                     end
    129             endcase
    130         
    131         end
    132         
    133 endmodule

    5、M2程序

       

      1 //描述M2模块的verilog程序
      2 //按照协议接受串行数据,进行处理并按照数据值在相应位输出高电平。
      3 module out16hi(scl,sda,outhigh);
      4 
      5 inout scl,sda;//串行数据输入
      6 output [15:0] outhigh;//根据输入的串行数据和设置高电平位
      7 
      8 reg[5:0] mstate/*synthesis preserve*/;//本模块的主状态
      9 reg[3:0] pdata,pdatabuf;
     10 reg[15:0] outhigh;//输出寄存器
     11 reg startflag,endflag;//数据开始和结束标志
     12 
     13 always@(negedge sda)//当数据是高电平
     14     begin
     15         if(scl)//如果时钟也是高
     16             begin
     17                 startflag<=1;//开始标志位置1
     18             end
     19         else if(endflag)//如果结束标志位是1
     20             startflag<=0;//那么开始标志位是0
     21     end
     22 
     23 always@(posedge sda)//如果数据线是上升沿
     24     if(scl)//如果时钟是高
     25         begin
     26             endflag<=1;
     27             pdatabuf<=pdata;
     28         end
     29     else    
     30         endflag<=0;
     31 
     32 parameter    ready=6'b00_0000,
     33             sbit0=6'b00_0001,
     34             sbit1=6'b00_0010,
     35             sbit2=6'b00_0100,
     36             sbit3=6'b00_1000,
     37             sbit4=6'b01_0000;
     38             
     39 always@(pdatabuf)
     40     begin
     41         case(pdatabuf)
     42             4'b0001:
     43                 outhigh=16'b0000_0000_0000_0001;
     44             4'b0010:
     45                 outhigh=16'b0000_0000_0000_0010;
     46             4'b0011:
     47                 outhigh=16'b0000_0000_0000_0100;
     48             4'b0100:
     49                 outhigh=16'b0000_0000_0000_1000;
     50             4'b0101:
     51                 outhigh=16'b0000_0000_0001_0000;
     52             4'b0110:
     53                 outhigh=16'b0000_0000_0010_0000;
     54             4'b0111:
     55                 outhigh=16'b0000_0000_0100_0000;
     56             4'b1000:
     57                 outhigh=16'b0000_0000_1000_0000;
     58             4'b1001:
     59                 outhigh=16'b0000_0001_0000_0000;
     60             4'b1010:
     61                 outhigh=16'b0000_0010_0000_0000;
     62             4'b1011:
     63                 outhigh=16'b0000_0100_0000_0000;
     64             4'b1100:
     65                 outhigh=16'b0000_1000_0000_0000;
     66             4'b1101:
     67                 outhigh=16'b0001_0000_0000_0000;
     68             4'b1110:
     69                 outhigh=16'b0010_0000_0000_0000;
     70             4'b1111:
     71                 outhigh=16'b0100_0000_0000_0000;
     72             4'b0000:
     73                 outhigh=16'b1000_0000_0000_0000;
     74         endcase
     75         
     76     end
     77     
     78 always@(posedge scl)
     79     if(startflag)
     80         case(mstate)
     81             sbit0:
     82                 begin
     83                     mstate<=sbit1;
     84                     pdata[3]<=sda;
     85                     $display("I am in sdabit0");
     86                 end
     87             sbit1:
     88                 begin
     89                     mstate<=sbit2;
     90                     pdata[2]<=sda;
     91                     $display("I am in sdabit1");
     92                 end
     93             sbit2:
     94                 begin
     95                     mstate<=sbit3;
     96                     pdata[1]<=sda;
     97                     $display("I am in sdabit2");
     98                 end
     99             sbit3:
    100                 begin
    101                     mstate<=sbit4;
    102                     pdata[0]<=sda;
    103                     $display("I am in sdabit3");
    104                 end
    105             sbit4:
    106                 begin
    107                     mstate<=sbit0;
    108                     $display("I am in sdastop");
    109                 end
    110             default:
    111                 mstate<=sbit0;
    112         endcase
    113     else
    114         mstate<=sbit0;
    115 endmodule
    116 
    117     
    118     

    6、M0程序

     1 //M0模块的verilog代码
     2 //本模块产生测试信号对设计中的模块进行测试
     3 `timescale 1ns/1ns
     4 `define halfperiod 50
     5 module sigdata(rst,sclk,data,ask_for_data);
     6 output rst;
     7 output[3:0] data;
     8 output sclk;
     9 input ask_for_data;
    10 reg rst,sclk;
    11 reg[3:0] data;
    12 
    13 initial
    14     begin
    15         rst=1;
    16         #10 rst=0;
    17         #(`halfperiod*2+3) rst=1;
    18     end
    19     
    20 initial
    21     begin
    22         sclk=0;
    23         data=0;
    24         #(`halfperiod*1000)
    25         $stop;
    26     end
    27     
    28 always #(`halfperiod) sclk=~sclk;
    29 
    30 always@(posedge ask_for_data)
    31     begin
    32         #(`halfperiod/2+3)
    33         data=data+1;
    34     end
    35     
    36 endmodule

    7、top.v程序

     1 //描述顶层模块
     2 //对所涉及的两个综合模块ptosda和out16hi进行联合测试
     3 `timescale 1ns/1ns
     4 `include "sigdata.v"
     5 `include "ptosda.v"
     6 `include "out16hi.v"
     7 
     8 module top;
     9     wire[3:0] data;
    10     wire sclk;
    11     wire scl;
    12     wire sda;
    13     wire rst;
    14     wire[15:0] outhigh;
    15     
    16     sigdata m0 (.rst(rst),.sclk(sclk),.data(data),.ask_for_data(ack));
    17     ptosda m1 (.rst(rst),.sclk(sclk),.ack(ack),.scl(scl),.sda(sda),.data(data));
    18     out16hi m2 (.scl(scl),.sda(sda),.outhigh(outhigh));
    19     
    20 endmodule
  • 相关阅读:
    史上最全的正则表达式-匹配中英文、字母和数字
    使用Git分支开发新特性或修复Bug与使用Git分支开发新特性或修复Bug
    装了Yaml 然后代码一运行就报错 YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe.
    mac安装yaml
    如何获取android app的package和Activity
    Original error: No Chromedriver found that can automate Chrome '39.0.0'.
    mac chromedriver安装
    keycode相关方法
    python+appium的物理按键代码
    Python测试Websocket接口
  • 原文地址:https://www.cnblogs.com/qidaiymm/p/4906685.html
Copyright © 2011-2022 走看看