|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
}& B: k5 n, p. t9 l! L a1 K2 a2 `6 j6 _( @- z3 R
这是特权同学在《深入浅出玩转FPGA》里面的“基于FPGA的跨时钟域信号处理”一章里面的一个例子,以此来强调同步设计思想。该程序因为脉冲信号和由CPU控制总线产生的选通信号是来至两个异步时钟域的信号,它们作为内部时钟信号时,如果同一时刻出现一个时钟在写寄存器counter,另一个时钟在读寄存器counter,那么很明显存在发生冲突的可能。. n, u2 a4 |0 v8 A( I
module fp(
! G3 u& \7 e6 p5 G; E7 t8 t clk,, p3 h; V5 G2 M9 n2 A. `1 m
rst,
' ]1 w, q$ R( T pulse, //脉冲信号,高电平有效7 \4 D+ M* [, r# v: A2 }
cs_n, //低电平有效2 U# f9 x$ i( l' s' ?
rd_n, //读使能信号,低电平有效
+ J' r. ~+ a L& y4 n addr_bus, //地址总线2 H* k( Y* _) K
data_bus //数据总线
+ r( T2 |! d: S' \7 [6 V );
3 @" k5 N* N+ D0 H# ^( b0 B$ \% [ input clk;
9 l; |/ D8 m2 q input rst;9 e4 t/ Z' S) r& W
input plush;. A/ `' e+ {' D3 c
input cs_n;
/ A4 F* c! L; j, ], X' U input rd_n;* k6 g; b8 t9 y, Z
input [3:0] addr_bus;' @; a# m" Z) n6 a: w* N( _2 r
3 _4 D2 Q k l& K$ C4 p
output [15:0] data_bus;
4 {0 ]4 W7 ^7 C0 l: I D: Z! |
3 x2 N$ A- E; H3 e$ Y reg [15:0] counter;
5 G, C4 d7 Z( e3 y$ b6 u b% G reg [15:0] data_bus;
, z" h: |* z' g
" @6 W" y# h. Z; i/ _ always @(posedge plush or negedge rst)! z2 |+ o6 @' e6 J ?- K
if(!rst) $ f4 K6 N, W* S, c
counter <= 16'b0;) v% I( [) W9 M- z! X8 ?% ]" Q! W
else if(plush)
$ x# P) ^( x4 G counter <= counter + 1'b1;
" b9 Z: {2 L# c1 i7 L , o; `" A; x: z9 G# c7 i1 A% |) `
wire DSP_cs = cs_en || rd_en;
9 t" f8 g; h+ A always @(dsp_cs or addr_bus)
3 @3 r3 S1 m9 F' ^ if(dsp_cs)
! U- ~3 X- Y2 D# r) ?- Z5 z data_bus <= 16'hzzzz;
2 ^3 b7 z- R# z. E b1 m5 o+ q else begin
/ E& @2 k$ V, y1 \ case (addr_bus)! M7 E8 w+ d9 \% [: c
4'h0: data_bus <= counter;
7 i) a" N4 l: C1 h: }& A ...
, G: G6 Y. z4 G$ a, D endcase0 ]! u3 \3 y7 E
end
: q4 b6 o* X# a# O endmodule
/ v9 ?3 n' c: c) u% k- u& Y% f
& `1 b' p/ K7 A 该例同步设计方法:先使用脉冲同步法把脉冲信号与系统时钟信号clk同步,然后使用脉冲同步法得到一个系统时钟宽度的使能信号作为数据锁存信号,同时也将CPU的控制信号与系统时钟信号同步。本人根据这个思想写了如下程序。我的疑问是同一个时刻clk出现写counter和读counter,怎么不会发生数据冲突。
1 {. T9 J6 ~3 @) Q: h% L1 \! n5 Jmodule fp(
1 H6 B: [7 u6 a. ]( ^# R clk,
# \& R5 x0 x3 t ]# j( H! o. q: C rst,
2 T( X3 h' V2 U# d8 ~6 G, ~+ R pulse, //脉冲信号,高电平有效5 J6 O+ X; ~: p: ? Q# f, B
cs_n, //低电平有效* E# k: B' ~. p2 O6 x* p' s" P
rd_n, //读使能信号,低电平有效
2 V9 C% J1 P6 G! }/ Q addr_bus, //地址总线
$ D: f/ M% P, H# L* |/ b- U4 y data_bus //数据总线
4 d) B- A+ [* i P );
3 Z) ^7 ^5 o9 m: K) \input clk;
3 H4 X3 n+ P7 F+ `input rst;
1 | W! M# z3 x: J' Finput plush;* V8 p2 g8 \' u+ @
input cs_n; E- P/ S4 J+ F, o0 \
input rd_n;
7 p) C" C$ |( W- L( @6 Binput [3:0] addr_bus;0 b0 K. E: r7 y; Z! Z
- `4 u% I% K' s0 f
output [15:0] data_bus;
- V! p/ t9 L& H- x1 \* v, z( B1 u( t' \) |) w- b: H
reg [15:0] counter;
) X0 z/ b' {: B# r6 R) p6 `reg [15:0] data_bus;
% J2 V# b% W5 n5 q5 ^! e$ `$ |6 {; _* P0 j
reg preg1,preg2;( x3 ^$ C2 Q2 x' ?$ B/ y" q9 V
always @(posedge clk or negedge rst)7 r, ^/ x% W. F
if(!rst) begin5 u9 ]! Q b+ Q8 r1 C* a7 t2 l$ z7 e
preg1 <= 1'b1;
& L* T, S0 i; q8 _ preg2 <= 1'b1;* ]/ X# }! ^7 Y9 s
end, Z# F/ }9 V% t4 \4 c
else begin/ Y `+ t% M% y4 u4 }$ W+ ?9 ]
preg1 <= plush;
& C) `2 R% m2 [7 p/ y- q: Q preg2 <= preg1;5 T! M1 s7 s3 C- m( R
end
$ O2 C9 f6 {6 M( [$ N# Hwire pos_en;( E, l6 l2 s& U
assign pos_en = preg1 & (~preg2); //检测脉冲信号,一个时钟周期有效的高电平 : I* ?, Y# k i2 _/ c# a6 O
/ D: \0 [. s9 r! v7 _! X/ nalways @(posedge clk or negedge rst)
2 J% S% H, H4 `% S! f if(!rst) : S8 g! S4 q1 S$ X8 J
counter <= 16'b0;
2 Y8 n. k" y" ? else if(pos_en)
3 w" `/ O% V8 l! V& | counter <= counter + 1'b1;
9 I- a% I9 r( V7 o
8 g' X$ W, D. n; d; O
# v$ V& M1 P) G, K* kwire pos_en = cs_en || rd_en; //片选信号和读信号同时为低时,对地址总线进行译码,把采样脉冲值送给数据总线6 {+ Y5 N% J$ a" N. A
reg dreg1,dreg2;! ?- ?/ Y+ l+ ^/ W
always @(posedge clk or negedge rst)
& ^$ A( g, q2 q' J4 a& ` if(!rst) begin
+ E# L7 T. D. R% ` dreg1 <= 1'b1;0 i" T" L5 i+ X* z( l
dreg2 <= 1'b1;* l/ H1 j3 r$ D2 a
end, v3 S1 L; @) \, o: _/ B
else begin' T( Z: R0 `. N/ P
dreg1 <= ce_en;
. n$ i9 j4 y s2 a" Q dreg2 <= preg1;6 b" g4 L, Z: {2 D, A
end; j. P) M) j+ W; v% `
wire dsp_cs;
7 Y3 Z( L/ o1 L/ P# p6 [assign dsp_cs = dreg2 & (~dreg1); //使能信号6 f$ J5 |# ^ q. i
s6 K* b4 {1 O: N/ y c
always @(posedge clk or negedge rst); O! L/ D! k0 e) j
if(!rst)
* i4 Y3 R L- Q7 I data_bus <= 16'hzzzz;
! T( w8 [+ K/ V; o! F else if(dsp_cs) begin) A3 e0 [3 [4 r' m; x- i6 s
case (addr_bus); v) k3 e4 r- H7 j. T
4'h0: data_bus <= counter;+ r& c w9 E) L
...
3 f _: i& x1 q* W" Y4 \0 R endcase
. v& S' h% b4 tend
2 t' r; u2 \% qendmodule. k' c% G2 M% ~7 L
|
|