较复杂时序逻辑电路设计实践一

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
原文地址:https://www.cnblogs.com/qidaiymm/p/4906685.html