lanlingshan

 

非阻塞的一点儿问题

 

一、用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)以及状态机的对应状态是关键。

posted on 2012-03-12 11:01  lanlingshan  阅读(226)  评论(0编辑  收藏  举报

导航