-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathva_037.v
245 lines (227 loc) · 7.12 KB
/
va_037.v
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
//
// Copyright (c) 2013 by 1801BM1@gmail.com
//
// The reformatted Verilog HDL model of 1801VP1-037
// 17-Oct-2015 - PIN_nE corrected
//______________________________________________________________________________
//
`timescale 1 ns / 1 ps
module va_037
(
input PIN_CLK, //
input PIN_R, //
input PIN_C, //
//
inout[15:0] PIN_nAD, // Address/Data inverted bus
input PIN_nSYNC, //
input PIN_nDIN, //
input PIN_nDOUT, //
input PIN_nWTBT, //
output PIN_nRPLY, //
//
output[6:0] PIN_A, //
output[1:0] PIN_nCAS, //
output PIN_nRAS, //
output PIN_nWE, //
//
output PIN_nE, //
output PIN_nBS, //
output PIN_WTI, //
output PIN_WTD, //
output PIN_nVSYNC //
);
//______________________________________________________________________________
//
reg nWTBT; // BYTE flag
reg [15:0] A; // Q-bus address latch
reg [7:0] RA; // 177664 register start address
reg M256; // 1/4 screen mode
//
wire RWR, ROE; // 177664 register strobes
//
wire RESET; // external reset
wire CLKIN; // external clock (pixel/2)
//
reg [2:0] PC; // pixel counter
reg [13:1] VA; // video address counter
reg [7:0] LC; // line counter
//
wire ALOAD, TV51; // base address load strobe
reg HGATE, VGATE; //
reg PC90; //
reg RASEL, AMUXSEL;//
wire CAS; //
reg CAS322; //
wire FREEZ; //
//
reg VTSYN; //
wire SYNC2, SYNC5; //
//
wire RPLY; //
reg TRPLY; //
//
//______________________________________________________________________________
//
assign PIN_nRPLY = (ROE | RWR | RPLY) ? 1'b0 : 1'bZ;
assign PIN_nAD[7:0] = ~ROE ? 8'hZZ : ~RA[7:0]; // read 177664 register back
assign PIN_nAD[8] = 1'bZ; //
assign PIN_nAD[9] = ~ROE ? 1'bZ : ~M256; //
assign PIN_nAD[14:10] = 5'hZZ; //
assign PIN_nAD[15] = (~PIN_nDIN & ~PIN_nSYNC & // start address vector 177716
(A[15:1] == (16'o177716 >> 1))) ? 1'b0 : 1'bZ;
assign PIN_nE = PIN_nSYNC | PIN_nDIN | (A[15:7] == (16'o177600 >> 7));
assign PIN_nBS = ~(A[15:2] == (16'o177660 >> 2));
// this replaces the original latch to reliably work with VM1
always @(*) nWTBT = PIN_nDOUT | PIN_nWTBT;
assign RWR = ~PIN_nSYNC & ~PIN_nDOUT & (A[15:1] == (16'o177664 >> 1));
assign ROE = ~PIN_nSYNC & ~PIN_nDIN & (A[15:1] == (16'o177664 >> 1));
assign RESET = PIN_R;
assign CLKIN = PIN_CLK;
always @(*) if (PIN_nSYNC) A[15:0] = ~PIN_nAD[15:0];
always @(*) if (RWR) RA[7:0] = ~PIN_nAD[7:0];
always @(*) if (RWR) M256 = ~PIN_nAD[9];
always @(*) if (RASEL) TRPLY = 1'b1; else if (PIN_nDIN & PIN_nDOUT) TRPLY = 1'b0;
assign RPLY = TRPLY & ~RASEL;
//______________________________________________________________________________
//
// Pixel counter (within word)
//
always @(negedge CLKIN) if (~PC[0]) PC90 <= PC[1];
always @(negedge CLKIN or posedge RESET)
begin
if (RESET)
PC[2:0] <= 3'b000;
else
PC[2:0] <= PC[2:0] + 3'b001;
end
//
// Word counter (within line)
//
always @(negedge CLKIN or posedge RESET)
begin
if (RESET)
VA[5:1] <= 5'b00000;
else
if (&PC[2:0])
begin
VA[4:1] <= VA[4:1] + 4'b0001;
if (&VA[4:1] & ~HGATE) VA[5] <= ~VA[5];
end
end
//
// Test clock assignment
//
assign TV51 = PIN_C ? 1'b0 : ~(&PC[2:0] & &VA[5:1]);
assign ALOAD = (FREEZ & ~LC[1]) | RESET;
//
// Loadable part of video address counter
//
always @(negedge CLKIN)
begin
if (ALOAD)
VA[13:6] <= RA[7:0];
else
if (~TV51 & ~FREEZ)
VA[13:6] <= VA[13:6] + 8'b00000001;
end
always @(negedge CLKIN or posedge RESET)
begin
if (RESET)
begin
HGATE <= 1'b0;
VGATE <= 1'b1;
end
else
begin
if (&PC[2:0] & &VA[4:1] & (HGATE | VA[5]))
HGATE <= ~HGATE;
if (~TV51 & (LC[5:0] == 6'b000000) & (VGATE | (LC[7:6] == 2'b00)))
VGATE <= ~VGATE;
end
end
//
// Line counter
//
always @(negedge CLKIN or posedge RESET)
begin
if (RESET)
LC[7:0] <= 8'b11111111;
else
if (~TV51)
begin
LC[5:0] <= LC[5:0] - 6'b000001;
if ((LC[5:0] == 6'b000000) & ~VGATE) LC[6] <= ~LC[6];
if ( LC[6:0] == 7'b0000000) LC[7] <= ~LC[7];
end
end
assign FREEZ = VGATE & (LC[5:2] == 4'b1010);
//______________________________________________________________________________
//
// DRAM address mux and controls
//
assign PIN_A[6:0] = RASEL ? (AMUXSEL ? ~A[7:1] : ~A[14:8])
: (AMUXSEL ? ~VA[7:1] : {1'b0, ~VA[13:8]});
assign PIN_nCAS[0] = ~(CAS & (~A[0] | ~PC[2] | nWTBT));
assign PIN_nCAS[1] = ~(CAS & ( A[0] | ~PC[2] | nWTBT));
assign PIN_nRAS = PC90 | (PC[2] & ~RASEL);
assign PIN_WTI = ~VGATE & ~HGATE & (M256 | (LC[6] & LC[7])) & PC90 & ~PC[2] & PC[1];
assign PIN_WTD = RPLY & ~PIN_nDIN;
assign PIN_nWE = ~(RASEL & ~PIN_nDOUT);
//
// Converted to synchronous flip-flop without asynch reset, generates the same waveform
//
// always @(posedge CLKIN or posedge (PC[1] & AMUXSEL))
// begin
// if (PC[1] & AMUXSEL)
// RASEL <= 1'b0;
// else
// if (PC90 & ~PC[1] & PC[2])
// RASEL <= ~(PIN_nSYNC | A[15] | RPLY | (PIN_nDIN & PIN_nDOUT));
// end
//
always @(posedge CLKIN) AMUXSEL <= PC90;
always @(posedge CLKIN)
begin
if (PC90 & PC[1])
RASEL <= 1'b0;
else
if (PC90 & ~PC[1] & PC[2])
RASEL <= ~(PIN_nSYNC | A[15] | RPLY | (PIN_nDIN & PIN_nDOUT));
end
always @(negedge CLKIN) CAS322 <= RASEL;
//assign CAS = ~(~(PC[1] & CAS322 & PC[2]) & (VGATE | HGATE | PC[2] | ~PC[1]));
assign CAS = (CAS322 & PC[1] & PC[2]) | (~VGATE & ~HGATE & PC[1] & ~PC[2]);
//______________________________________________________________________________
//
// Video synchronization
//
always @(negedge CLKIN or posedge RESET)
begin
if (RESET)
VTSYN <= 1'b0;
else
begin
if ((VA[3:1] == 3'b000) & (PC[1:0] == 2'b11))
VTSYN <= 1'b1;
if ((VA[4:1] == 4'b0100) & (PC[2:0] == 3'b111))
VTSYN <= 1'b0;
end
end
//
// Latch converted to clock synchronous flip-flop, generates the same waveform
//
// assign VTSET = (VA[3:1] == 3'b000) & PC[2];
// assign VTCLR = (VA[4:1] == 4'b0101);
//
// always @(*)
// begin
// if (VTCLR) VTSYN = 1'b0;
// if (VTSET) VTSYN = 1'b1;
// end
//
assign SYNC2 = ~(VGATE & (LC[5:2] == 4'b1010) & ~(LC[0] & LC[1]));
assign SYNC5 = VTSYN | (SYNC2 & ~HGATE);
assign PIN_nVSYNC = ~(SYNC2 ^ SYNC5);
//______________________________________________________________________________
//
endmodule