3
3
from migen .bank .description import *
4
4
from migen .bank import csrgen
5
5
6
- def _data_en (trigger , output , delay , duration ):
7
- dcounter = Signal (BV (4 ))
8
- dce = Signal ()
9
- return [
10
- If (trigger ,
11
- dcounter .eq (delay ),
12
- dce .eq (1 )
13
- ).Elif (dce ,
14
- dcounter .eq (dcounter - 1 ),
15
- If (dcounter == 0 ,
16
- If (~ output ,
17
- output .eq (1 ),
18
- dcounter .eq (duration )
19
- ).Else (
20
- output .eq (0 ),
21
- dce .eq (0 )
22
- )
23
- )
24
- )
25
- ]
6
+ class PhaseInjector :
7
+ def __init__ (self , phase ):
8
+ self .phase = phase
9
+
10
+ self ._cs = Field ("cs" , 1 , WRITE_ONLY , READ_ONLY )
11
+ self ._we = Field ("we" , 1 , WRITE_ONLY , READ_ONLY )
12
+ self ._cas = Field ("cas" , 1 , WRITE_ONLY , READ_ONLY )
13
+ self ._ras = Field ("ras" , 1 , WRITE_ONLY , READ_ONLY )
14
+ self ._wren = Field ("wren" , 1 , WRITE_ONLY , READ_ONLY )
15
+ self ._rden = Field ("rden" , 1 , WRITE_ONLY , READ_ONLY )
16
+ self ._command = RegisterFields ("command" ,
17
+ [self ._cs , self ._we , self ._cas , self ._ras , self ._wren , self ._rden ])
18
+
19
+ self ._address = RegisterField ("address" , self .phase .address .bv .width )
20
+ self ._baddress = RegisterField ("baddress" , self .phase .bank .bv .width )
21
+
22
+ self ._wrdata = RegisterField ("wrdata" , self .phase .wrdata .bv .width )
23
+ self ._rddata = RegisterField ("rddata" , self .phase .rddata .bv .width , READ_ONLY , WRITE_ONLY )
24
+
25
+ def get_registers (self ):
26
+ return [self ._command ,
27
+ self ._address , self ._baddress ,
28
+ self ._wrdata , self ._rddata ]
29
+
30
+ def get_fragment (self ):
31
+ comb = [
32
+ If (self ._command .re ,
33
+ self .phase .cs_n .eq (~ self ._cs .r ),
34
+ self .phase .we_n .eq (~ self ._we .r ),
35
+ self .phase .cas_n .eq (~ self ._cas .r ),
36
+ self .phase .ras_n .eq (~ self ._ras .r )
37
+ ).Else (
38
+ self .phase .cs_n .eq (1 ),
39
+ self .phase .we_n .eq (1 ),
40
+ self .phase .cas_n .eq (1 ),
41
+ self .phase .ras_n .eq (1 )
42
+ ),
43
+ self .phase .address .eq (self ._address .field .r ),
44
+ self .phase .bank .eq (self ._baddress .field .r ),
45
+ self .phase .wrdata .eq (self ._wrdata .field .r )
46
+ ]
47
+ sync = [
48
+ self .phase .wrdata_en .eq (self ._command .re & self ._wren .r ),
49
+ self .phase .rddata_en .eq (self ._command .re & self ._rden .r ),
50
+ If (self .phase .rddata_valid , self ._rddata .field .w .eq (self .phase .rddata ))
51
+ ]
52
+ return Fragment (comb , sync )
26
53
27
54
class DFIInjector :
28
55
def __init__ (self , csr_address , a , ba , d , nphases = 1 ):
@@ -34,84 +61,19 @@ def __init__(self, csr_address, a, ba, d, nphases=1):
34
61
self ._cke = Field ("cke" )
35
62
self ._control = RegisterFields ("control" , [self ._sel , self ._cke ])
36
63
37
- self ._cs = Field ("cs" , 1 , WRITE_ONLY , READ_ONLY )
38
- self ._we = Field ("we" , 1 , WRITE_ONLY , READ_ONLY )
39
- self ._cas = Field ("cas" , 1 , WRITE_ONLY , READ_ONLY )
40
- self ._ras = Field ("ras" , 1 , WRITE_ONLY , READ_ONLY )
41
- self ._rddata = Field ("rddata" , 1 , WRITE_ONLY , READ_ONLY )
42
- self ._wrdata = Field ("wrdata" , 1 , WRITE_ONLY , READ_ONLY )
43
- self ._command = RegisterFields ("command" ,
44
- [self ._cs , self ._we , self ._cas , self ._ras , self ._rddata , self ._wrdata ])
45
-
46
- self ._address = RegisterField ("address" , a )
47
- self ._baddress = RegisterField ("baddress" , ba )
64
+ self ._phase_injectors = [PhaseInjector (phase ) for phase in self ._int .phases ]
48
65
49
- self ._rddelay = RegisterField ("rddelay" , 4 , reset = 5 )
50
- self ._rdduration = RegisterField ("rdduration" , 3 , reset = 0 )
51
- self ._wrdelay = RegisterField ("wrdelay" , 4 , reset = 3 )
52
- self ._wrduration = RegisterField ("wrduration" , 3 , reset = 0 )
53
-
54
- self .bank = csrgen .Bank ([
55
- self ._control , self ._command ,
56
- self ._address , self ._baddress ,
57
- self ._rddelay , self ._rdduration ,
58
- self ._wrdelay , self ._wrduration
59
- ], address = csr_address )
66
+ registers = sum ([pi .get_registers () for pi in self ._phase_injectors ], [self ._control ])
67
+ self .bank = csrgen .Bank (registers , address = csr_address )
60
68
61
69
def get_fragment (self ):
62
- comb = []
63
- sync = []
64
-
65
- # mux
66
70
connect_int = dfi .interconnect_stmts (self ._int , self .master )
67
71
connect_slave = dfi .interconnect_stmts (self .slave , self .master )
68
- comb .append (If (self ._sel .r , * connect_slave ).Else (* connect_int ))
69
-
70
- # phases
71
- rddata_en = Signal ()
72
- wrdata_en = Signal ()
73
- for phase in self ._int .phases :
74
- comb += [
75
- phase .cke .eq (self ._cke .r ),
76
- phase .rddata_en .eq (rddata_en ),
77
- phase .wrdata_en .eq (wrdata_en )
78
- ]
79
- cmdphase = self ._int .phases [0 ]
80
- for phase in self ._int .phases [1 :]:
81
- comb += [
82
- phase .cs_n .eq (1 ),
83
- phase .we_n .eq (1 ),
84
- phase .cas_n .eq (1 ),
85
- phase .ras_n .eq (1 )
86
- ]
87
-
88
- # commands
89
- comb += [
90
- If (self ._command .re ,
91
- cmdphase .cs_n .eq (~ self ._cs .r ),
92
- cmdphase .we_n .eq (~ self ._we .r ),
93
- cmdphase .cas_n .eq (~ self ._cas .r ),
94
- cmdphase .ras_n .eq (~ self ._ras .r )
95
- ).Else (
96
- cmdphase .cs_n .eq (1 ),
97
- cmdphase .we_n .eq (1 ),
98
- cmdphase .cas_n .eq (1 ),
99
- cmdphase .ras_n .eq (1 )
100
- )
72
+ comb = [
73
+ If (self ._sel .r , * connect_slave ).Else (* connect_int )
101
74
]
75
+ comb += [phase .cke .eq (self ._cke .r ) for phase in self ._int .phases ]
102
76
103
- # addresses
104
- comb += [
105
- cmdphase .address .eq (self ._address .field .r ),
106
- cmdphase .bank .eq (self ._baddress .field .r )
107
- ]
108
-
109
- # data enables
110
- sync += _data_en (self ._command .re & self ._rddata .r ,
111
- rddata_en ,
112
- self ._rddelay .field .r , self ._rdduration .field .r )
113
- sync += _data_en (self ._command .re & self ._wrdata .r ,
114
- wrdata_en ,
115
- self ._wrdelay .field .r , self ._wrduration .field .r )
116
-
117
- return Fragment (comb , sync ) + self .bank .get_fragment ()
77
+ return Fragment (comb ) \
78
+ + sum ([pi .get_fragment () for pi in self ._phase_injectors ], Fragment ()) \
79
+ + self .bank .get_fragment ()
0 commit comments