MBCtrl.v
3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
module MBCtrl (
memclk,
Reset,
Length,
Addr,
I,
D,
M36,
Bk0StA2,
Bk1StA2,
Bk0LastStA3,
Bk1LastStA3,
Bk0LastCAS,
Bk1LastCAS,
StB0,
StB1,
nxt_StB1,
StB2,
StB5,
Bk0MBAct,
Bk1MBAct,
Bk0MB1stAct,
Bk1MB1stAct,
SBSel
);
input memclk;
input Reset;
input [6:0] Length;
input [6:3] Addr;
input I;
input D;
input M36;
input Bk0StA2;
input Bk1StA2;
input Bk0LastStA3;
input Bk1LastStA3;
input Bk0LastCAS;
input Bk1LastCAS;
output [7:0] StB0;
output StB1;
output nxt_StB1;
output StB2;
output StB5;
output Bk0MBAct;
output Bk1MBAct;
output Bk0MB1stAct;
output Bk1MB1stAct;
output SBSel;
reg SameBk0;
reg SameBk1;
reg [7:0] StB0;
reg lStB0;
wire nxt_SameBk0 = lStB0 ? Bk0StA2 : SameBk0;
wire nxt_SameBk1 = lStB0 ? Bk1StA2 : SameBk1;
always @(posedge memclk) begin
if (Reset) SameBk0 <= 1'b0;
else SameBk0 <= nxt_SameBk0;
if (Reset) SameBk1 <= 1'b0;
else SameBk1 <= nxt_SameBk1;
end
wire SameLastStA3 = SameBk0 & Bk0LastStA3
| SameBk1 & Bk1LastStA3;
wire OppoLastStA3 = SameBk1 & Bk0LastStA3
| SameBk0 & Bk1LastStA3;
// Compute B,
// same as BankCtrl.v
// For M36:
// B[7:6] = number of bank accesses (lenght + starting
// address double word offset into bank (i.e. 64 byte
// alligned block)
// EA[5:3] = ending adddress double word offset
// For M64:
// B[7] = number of bank accesses (128 byte alligned block)
// EA[6:3] = ending adddress double word offset
wire [7:3] EAup = Length[6:3] + (I ? 4'b0
: (M36 ? {1'b0,Addr[6:4]}
: Addr[6:3]));
wire [7:3] EAdn = ~Length[6:3] + 4'b1 + (M36 ? {1'b0,Addr[6:4]}
: Addr[6:3]);
wire [7:6] B = D ? {(EAdn[7] ^ EAdn[6]),EAdn[6]} : EAup[7:6];
// Multi-Bank State Machine
reg StB1;
reg StB2;
reg StB5;
reg StB6;
wire nxt_StB0 = lStB0 & ~Bk0StA2 & ~Bk1StA2
| lStB0 & (B[7:6]==2'h0) & M36
| lStB0 & ~B[7] & ~M36
| StB6 & Bk0LastCAS
| StB6 & Bk1LastCAS
| Reset;
wire nxt_StB1 = ~Reset & lStB0 & Bk0StA2 & ~(B[7:6]==2'h0) & M36
| ~Reset & lStB0 & Bk1StA2 & ~(B[7:6]==2'h0) & M36
| ~Reset & lStB0 & Bk0StA2 & B[7] & ~M36
| ~Reset & lStB0 & Bk1StA2 & B[7] & ~M36
| ~Reset & StB1 & ~SameLastStA3;
wire nxt_StB2 = ~Reset & StB1 & SameLastStA3 & (B[7:6]==2'h2) & M36
| ~Reset & StB2 & ~OppoLastStA3;
wire nxt_StB5 = ~Reset & StB1 & SameLastStA3 & (B[7:6]==2'h1) & M36
| ~Reset & StB1 & SameLastStA3 & B[7] & ~M36
| ~Reset & StB2 & OppoLastStA3 & (B[7:6]==2'h2) & M36
| ~Reset & StB5 & ~SameLastStA3 & ~OppoLastStA3;
wire nxt_StB6 = ~Reset & StB5 & OppoLastStA3
| ~Reset & StB5 & SameLastStA3
| ~Reset & StB6 & ~Bk0LastCAS & ~Bk1LastCAS;
always @(posedge memclk) begin
lStB0 <= nxt_StB0;
StB0 <= {8{nxt_StB0}};
StB1 <= nxt_StB1;
StB2 <= nxt_StB2;
StB5 <= nxt_StB5;
StB6 <= nxt_StB6;
end
wire ActSame = OppoLastStA3 & StB2;
wire ActOppo = SameLastStA3 & StB1;
wire Bk0MBAct = SameBk0 & ActSame | SameBk1 & ActOppo;
wire Bk1MBAct = SameBk1 & ActSame | SameBk0 & ActOppo;
wire Bk0MB1stAct = SameBk1 & StB1 & SameLastStA3;
wire Bk1MB1stAct = SameBk0 & StB1 & SameLastStA3;
reg SBk0Sel;
wire nxt_SBk0Sel = ~SBk0Sel & lStB0 & Bk0StA2 & (B[7:6]==2'h0) & M36
| ~SBk0Sel & lStB0 & Bk0StA2 & ~B[7] & ~M36
| SBk0Sel & ~Bk0LastCAS;
always @(posedge memclk)
if (Reset) SBk0Sel <= 1'b0;
else SBk0Sel <= nxt_SBk0Sel;
reg SBk1Sel;
wire nxt_SBk1Sel = ~SBk1Sel & lStB0 & Bk1StA2 & (B[7:6]==2'h0) & M36
| ~SBk1Sel & lStB0 & Bk1StA2 & ~B[7] & ~M36
| SBk1Sel & ~Bk1LastCAS;
always @(posedge memclk)
if (Reset) SBk1Sel <= 1'b0;
else SBk1Sel <= nxt_SBk1Sel;
wire SBSel = SBk0Sel | SBk1Sel;
endmodule