OpenCores
URL https://opencores.org/ocsvn/adv_debug_sys/adv_debug_sys/trunk

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Hardware/] [adv_dbg_if/] [rtl/] [verilog/] [syncreg.v] - Blame information for rev 42

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 42 nyawn
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  syncreg.v                                                   ////
4
////                                                              ////
5
////                                                              ////
6
////  Synchronizes a register between two clock domains           ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////       Nathan Yawn (nathan.yawn@opencores.org)                ////
10
////                                                              ////
11
////                                                              ////
12
////                                                              ////
13
//////////////////////////////////////////////////////////////////////
14
////                                                              ////
15
//// Copyright (C) 2010 Authors                                   ////
16
////                                                              ////
17
//// This source file may be used and distributed without         ////
18
//// restriction provided that this copyright statement is not    ////
19
//// removed from the file and that any derivative work contains  ////
20
//// the original copyright notice and the associated disclaimer. ////
21
////                                                              ////
22
//// This source file is free software; you can redistribute it   ////
23
//// and/or modify it under the terms of the GNU Lesser General   ////
24
//// Public License as published by the Free Software Foundation; ////
25
//// either version 2.1 of the License, or (at your option) any   ////
26
//// later version.                                               ////
27
////                                                              ////
28
//// This source is distributed in the hope that it will be       ////
29
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
30
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
31
//// PURPOSE.  See the GNU Lesser General Public License for more ////
32
//// details.                                                     ////
33
////                                                              ////
34
//// You should have received a copy of the GNU Lesser General    ////
35
//// Public License along with this source; if not, download it   ////
36
//// from http://www.opencores.org/lgpl.shtml                     ////
37
////                                                              ////
38
//////////////////////////////////////////////////////////////////////
39
//
40
// This is a synchronization element between two clock domains. Domain A
41
// is considered the 'source' domain (produces the data), and Domain B
42
// is considered the 'destination' domain (consumes the data).  It is assumed
43
// that clock A is faster than clock B, but this element will work
44
// regardless.  The idea here is NOT to insure that domain B sees every
45
// change to the value generated by domain A.  Rather, this device
46
// attempts to keep the value seen by domain B as current as possible,
47
// always updating to the latest value of the input in domain A.
48
// Thus, there may be dozens or hundreds of changes to register A
49
// which are not seen by domain B.  There is no external acknowledge
50
// of receipt from domain B.  Domain B simply wants the most current
51
// value of register A possible at any given time.
52
// Note the reset is asynchronous; this is necessary to coordinate between
53
// two clock domains which may have separate reset signals.  I could find
54
// no other way to insure correct initialization with two separate 
55
// reset signals.
56
//
57
// Ports:
58
// CLKA:  Clock for the source domain
59
// CLKB:  Clock for the destination domain
60
// RST:  Asynchronously resets all sync elements, prepares
61
//       unit for operation.
62
// DATA_IN:  Data input from clock domain A
63
// DATA_OUT: Data output to clock domain B
64
// 
65
 
66
 
67
// Top module
68
module syncreg (
69
                CLKA,
70
                CLKB,
71
                RST,
72
                DATA_IN,
73
                DATA_OUT
74
                );
75
 
76
 
77
   input   CLKA;
78
   input   CLKB;
79
   input   RST;
80
   input   [3:0] DATA_IN;
81
   output  [3:0] DATA_OUT;
82
 
83
   reg     [3:0] regA;
84
   reg     [3:0] regB;
85
   reg     strobe_toggle;
86
   reg     ack_toggle;
87
 
88
   wire    A_not_equal;
89
   wire    A_enable;
90
   wire    strobe_sff_out;
91
   wire    ack_sff_out;
92
   wire [3:0]   DATA_OUT;
93
 
94
   // Combinatorial assignments
95
   assign  A_enable = A_not_equal & ack_sff_out;
96
   assign  A_not_equal = !(DATA_IN == regA);
97
   assign DATA_OUT = regB;
98
 
99
   // register A (latches input any time it changes)
100
   always @ (posedge CLKA or posedge RST)
101
     begin
102
        if(RST)
103
          regA <= 4'b0;
104
        else if(A_enable)
105
          regA <= DATA_IN;
106
     end
107
 
108
 
109
   // register B (latches data from regA when enabled by the strobe SFF)
110
   always @ (posedge CLKB or posedge RST)
111
     begin
112
        if(RST)
113
          regB <= 4'b0;
114
        else if(strobe_sff_out)
115
          regB <= regA;
116
     end
117
 
118
 
119
   // 'strobe' toggle FF
120
   always @ (posedge CLKA or posedge RST)
121
     begin
122
        if(RST)
123
          strobe_toggle <= 1'b0;
124
        else if(A_enable)
125
          strobe_toggle <= ~strobe_toggle;
126
     end
127
 
128
 
129
   // 'ack' toggle FF
130
   // This is set to '1' at reset, to initialize the unit.
131
   always @ (posedge CLKB or posedge RST)
132
     begin
133
        if(RST)
134
          ack_toggle <= 1'b1;
135
        else if (strobe_sff_out)
136
          ack_toggle <= ~ack_toggle;
137
     end
138
 
139
   // 'strobe' sync element
140
   syncflop strobe_sff (
141
                        .DEST_CLK (CLKB),
142
                        .D_SET (1'b0),
143
                        .D_RST (strobe_sff_out),
144
                        .RESET (RST),
145
                        .TOGGLE_IN (strobe_toggle),
146
                        .D_OUT (strobe_sff_out)
147
                        );
148
 
149
   // 'ack' sync element
150
   syncflop ack_sff (
151
                     .DEST_CLK (CLKA),
152
                     .D_SET (1'b0),
153
                     .D_RST (A_enable),
154
                     .RESET (RST),
155
                     .TOGGLE_IN (ack_toggle),
156
                     .D_OUT (ack_sff_out)
157
                     );
158
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.