zoukankan      html  css  js  c++  java
  • 非阻塞的一点儿问题

    一、用Quartus内部的双口ram的时序时非阻塞的问题:

    cnt
      1 /* 更新地址和数据 */
    2 reg [7:0]cnt;
    3 always @(negedge wrclk_div or negedge reset)//时序电路
    4 begin
    5 if(!reset)
    6 begin
    7 wraddress_reg<=0;
    8 wrdata<=0;
    9 end
    10 else if (~frame_end)//帧未传完
    11 begin
    12 if(~wrclock)//更新地址,更新数据
    13 begin
    14 wraddress_reg<=wraddress_reg+1;
    15 wrdata<=data_send;//非阻塞,每次赋值都是上一个写确定的值
    16 end
    17 else
    18 begin
    19 wraddress_reg<=wraddress_reg;
    20 wrdata<=wrdata;
    21 end
    22 end
    23 else
    24 begin
    25 wraddress_reg<=wraddress_reg;
    26 wrdata<=wrdata;
    27 end
    28
    29 end
    30 always @(negedge wrclk_div or negedge reset or posedge fre_20hz)//时序电路
    31 begin
    32 if(!reset)
    33 begin
    34 cnt<=0;
    35 frame_end<=0;
    36 end
    37 else if(~frame_end)//帧未传完
    38 begin
    39 if(~wrclock)
    40 begin
    41 if(cnt==31)
    42 begin
    43 cnt<=0;
    44 frame_end<=1;
    45 end
    46 else
    47 begin
    48 cnt<=cnt+1;
    49 end
    50 end
    51 else
    52 begin
    53 cnt<=cnt;
    54 end
    55 end
    56 else //帧传完
    57 begin
    58 if(fre_20hz)//下一帧
    59 begin
    60 cnt<=0;
    61 frame_end<=0;
    62 end
    63 else
    64 begin
    65 cnt<=0;
    66 frame_end<=frame_end;
    67 end
    68 end
    69 end
    70 always @(cnt)//组合电路
    71 begin
    72 case (cnt)
    73 0 :data_send=1 ;
    74 1 :data_send=2 ;
    75 2 :data_send=3 ;
    76 3 :data_send=4 ;
    77 4 :data_send=5 ;
    78 5 :data_send=6 ;
    79 6 :data_send=7 ;
    80 7 :data_send=8 ;
    81 8 :data_send=9 ;
    82 9 :data_send=10;
    83 10:data_send=11;
    84 11:data_send=12;
    85 12:data_send=13;
    86 13:data_send=14;
    87 14:data_send=15;
    88 15:data_send=16;
    89 16:data_send=17;
    90 17:data_send=18;
    91 18:data_send=19;
    92 19:data_send=20;
    93 20:data_send=21;
    94 21:data_send=22;
    95 22:data_send=23;
    96 23:data_send=24;
    97 24:data_send=25;
    98 25:data_send=26;
    99 26:data_send=27;
    100 27:data_send=28;
    101 28:data_send=29;
    102 29:data_send=30;
    103 30:data_send=31;
    104 31:data_send=0 ;
    105 endcase
    106
    107
    108 // case (cnt)
    109 // 1 :data_send=1 ;//这种方式下wrdata得到的值教data_send的值晚一个更新周期
    110 // 2 :data_send=2 ;
    111 // 3 :data_send=3 ;
    112 // 4 :data_send=4 ;
    113 // 5 :data_send=5 ;
    114 // 6 :data_send=6 ;
    115 // 7 :data_send=7 ;
    116 // 8 :data_send=8 ;
    117 // 9 :data_send=9 ;
    118 // 10:data_send=10;
    119 // 11:data_send=11;
    120 // 12:data_send=12;
    121 // 13:data_send=13;
    122 // 14:data_send=14;
    123 // 15:data_send=15;
    124 // 16:data_send=16;
    125 // 17:data_send=17;
    126 // 18:data_send=18;
    127 // 19:data_send=19;
    128 // 20:data_send=20;
    129 // 21:data_send=21;
    130 // 22:data_send=22;
    131 // 23:data_send=23;
    132 // 24:data_send=24;
    133 // 25:data_send=25;
    134 // 26:data_send=26;
    135 // 27:data_send=27;
    136 // 28:data_send=28;
    137 // 29:data_send=29;
    138 //30:data_send=30;

    139 // 31:data_send=31;
    140 // 0 :data_send=0;
    141 // endcase
    142 end

    图1

    图2

    分析:图1中cnt=0时,datasend=0;一个操作周期wrdata=之前的datasend=0;延时了一个操作周期,

      图2中cnt=0时,datasend=1;一个操作周期wrdata=之前的datasend=1;延时了一个周期,达到了目的

     二、SPI的一点儿问题,利用同样的思想,但是两个模块的时钟不一样

    SPI
     1 always @(negedge clk or negedge reset)//产生写信号,与pro_clk一个周期宽度的脉冲,下降沿
    2 begin //时序电路,敏感量clk,reset,与下不同
    3 if(!reset)
    4 begin
    5 write_reg<=2'b00;
    6 data_out<=8'h0;
    7 end
    8 else if(control_pulse)
    9 begin
    10 write_reg<=2'b11;
    11 data_out<=data_send;
    12 end
    13 else
    14 begin
    15 write_reg<=2'b00;
    16 end
    17 end
    18
    19 always @(posedge control_pulse or negedge reset or posedge fre_20hz)//时序电路
    20 begin //敏感量control_pul,reset,fre_20hz
    21 if(!reset)
    22 begin
    23 byte_count<=0;
    24 frame_end<=0;
    25 end
    26 else if (fre_20hz)//下一帧
    27 begin
    28 if(frame_end)
    29 begin
    30 frame_end<=0;
    31 byte_count<=0;//传下一帧的时候在把状态又变为0;
    32 end
    33 else
    34 frame_end<=frame_end;
    35 end
    36 else
    37 begin
    38 if(byte_count==31)
    39 begin
    40 byte_count<=0;
    41 frame_end<=1;
    42 end
    43 else
    44 begin
    45 byte_count<=byte_count+1;
    46 end
    47 end
    48 end
    49
    50 always @(byte_count)//组合逻辑
    51 begin
    52
    53 case (byte_count)
    54 0 :data_send<=29;
    55 1 :data_send<=8'haa;
    56 2 :data_send<=8'h55;
    57 3 :data_send<=0 ;
    58 4 :data_send<=1 ;
    59 5 :data_send<=2 ;
    60 6 :data_send<=3 ;
    61 7 :data_send<=4 ;
    62 8 :data_send<=5 ;
    63 9 :data_send<=6 ;
    64 10:data_send<=7 ;
    65 11:data_send<=8 ;
    66 12:data_send<=9 ;
    67 13:data_send<=10;
    68 14:data_send<=11;
    69 15:data_send<=12;
    70 16:data_send<=13;
    71 17:data_send<=14;
    72 18:data_send<=15;
    73 19:data_send<=16;
    74 20:data_send<=17;
    75 21:data_send<=18;
    76 22:data_send<=19;
    77 23:data_send<=20;
    78 24:data_send<=21;
    79 25:data_send<=22;
    80 26:data_send<=23;
    81 27:data_send<=24;
    82 28:data_send<=25;
    83 29:data_send<=26;
    84 30:data_send<=27;
    85 31:data_send<=28;
    86 endcase
    87 end

    仿真波形如下:

    图1(放大)

    图2(未放大)

    分析:虽然逻辑上跟双口RAM的相似,但是两个时序逻辑模块的敏感量不一样,不是延时的问题,因为byte_count和data_send为组合逻辑,不会延时一个周期,但是当control_pulse敏感量变化的时候导致byte_count的变化,此时byte_count又0+1=1;然后再一个clk的下降沿采样到control_pulse为高电平,把data_send赋值给data_out,故由上分析(1)正确的分析组合逻辑和时序逻辑(2)以及状态机的对应状态是关键。

  • 相关阅读:
    Android执行时ART载入OAT文件的过程分析
    Oracle GoldenGate 支持 从SAP HANA database抽取或者复制数据到SAP HANA database 吗?
    【机房收费系统C#版】——导出Excel
    【STL容器学习】-关联容器与map的用法
    IOS
    使用Android Studio 1.3 版本号进行NDK开发
    4443: [Scoi2015]小秃玩矩阵|二分答案|匈牙利
    多版本号并发控制(MVCC)在实际项目中的应用
    memcached远程 telnet 无法连接,解决方案
    Memcached 服务器端命令
  • 原文地址:https://www.cnblogs.com/lanlingshan/p/2391443.html
Copyright © 2011-2022 走看看