1 |
2 |
ndumitrach |
//////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// This file is part of the Next186 Soc PC project
|
4 |
|
|
// http://opencores.org/project,next186
|
5 |
|
|
//
|
6 |
|
|
// Filename: ddr_186.v
|
7 |
|
|
// Description: Part of the Next186 SoC PC project, main system, ddr interface
|
8 |
|
|
// Version 1.0
|
9 |
|
|
// Creation date: Apr2012
|
10 |
|
|
//
|
11 |
|
|
// Author: Nicolae Dumitrache
|
12 |
|
|
// e-mail: ndumitrache@opencores.org
|
13 |
|
|
//
|
14 |
|
|
/////////////////////////////////////////////////////////////////////////////////
|
15 |
|
|
//
|
16 |
|
|
// Copyright (C) 2012 Nicolae Dumitrache
|
17 |
|
|
//
|
18 |
|
|
// This source file may be used and distributed without
|
19 |
|
|
// restriction provided that this copyright statement is not
|
20 |
|
|
// removed from the file and that any derivative work contains
|
21 |
|
|
// the original copyright notice and the associated disclaimer.
|
22 |
|
|
//
|
23 |
|
|
// This source file is free software; you can redistribute it
|
24 |
|
|
// and/or modify it under the terms of the GNU Lesser General
|
25 |
|
|
// Public License as published by the Free Software Foundation;
|
26 |
|
|
// either version 2.1 of the License, or (at your option) any
|
27 |
|
|
// later version.
|
28 |
|
|
//
|
29 |
|
|
// This source is distributed in the hope that it will be
|
30 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied
|
31 |
|
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
32 |
|
|
// PURPOSE. See the GNU Lesser General Public License for more
|
33 |
|
|
// details.
|
34 |
|
|
//
|
35 |
|
|
// You should have received a copy of the GNU Lesser General
|
36 |
|
|
// Public License along with this source; if not, download it
|
37 |
|
|
// from http://www.opencores.org/lgpl.shtml
|
38 |
|
|
//
|
39 |
|
|
///////////////////////////////////////////////////////////////////////////////////
|
40 |
|
|
// Additional Comments:
|
41 |
|
|
//
|
42 |
|
|
// 25Apr2012 - added SD card SPI support
|
43 |
|
|
// 15May2012 - added PIT 8253 (sound + timer INT8)
|
44 |
|
|
// 24May2012 - added PIC 8259
|
45 |
|
|
// 28May2012 - RS232 boot loader does not depend on CPU speed anymore (uses timer0)
|
46 |
|
|
// 01Feb2013 - ADD 8042 PS2 Keyboard & Mouse controller
|
47 |
|
|
// 27Feb2013 - ADD RTC
|
48 |
|
|
// 04Apr2013 - ADD NMI, port 3bc for 8 leds
|
49 |
|
|
//
|
50 |
|
|
//Route:455 - CLK Net:u_ddr/top_00/dqs_int_delay_in<0> may have excessive skew because
|
51 |
|
|
// 22 CLK pins and 0 NON_CLK pins failed to route using a CLK template.
|
52 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
53 |
|
|
|
54 |
|
|
/* ----------------- implemented ports -------------------
|
55 |
|
|
0001 - write RS232 (bit0)
|
56 |
|
|
|
57 |
|
|
0021, 00a1 - interrupt controller data ports. R/W interrupt mask, 1disabled/0enabled (bit0=timer, bit1=keyboard, bit3=RTC, bit4=mouse)
|
58 |
|
|
|
59 |
|
|
0040-0043 - PIT 8253 ports
|
60 |
|
|
|
61 |
|
|
0x60, 0x64 - 8042 keyboard/mouse data and cfg
|
62 |
|
|
|
63 |
|
|
0061 - bits1:0 speaker on/off (write only)
|
64 |
|
|
|
65 |
|
|
0070 - RTC (16bit write only counter value). RTC is incremented with 1Mhz and at set value sends INT70h, then restart from 0
|
66 |
|
|
When set, it restarts from 0. If the set value is 0, it will send INT70h only once, if it was not already 0
|
67 |
|
|
|
68 |
|
|
080h-08fh - memory map: bit9:0=64 Kbytes DDRAM segment index (up to 1024 segs = 64MB), mapped over
|
69 |
|
|
PORT[3:0] 80186 addressable segment
|
70 |
|
|
|
71 |
|
|
03BC - parallel port (out only) LED[7:0]
|
72 |
|
|
|
73 |
|
|
03C0 - VGA mode (index 10h only)
|
74 |
|
|
bit0 = graphic(1)/text(0)
|
75 |
|
|
bit3 = text mode flash enabled(1)
|
76 |
|
|
bit6 = 320x200(1)/640x480(0)
|
77 |
|
|
|
78 |
|
|
03C6 - DAC mask (rw)
|
79 |
|
|
03C7 - DAC read index (rw)
|
80 |
|
|
03C8 - DAC write index (rw)
|
81 |
|
|
03C9 - DAC color (rw)
|
82 |
|
|
03CB - font: write WORD = set index (8 bit), r/w BYTE = r/w font data
|
83 |
|
|
|
84 |
|
|
03DA - read VGA status, bit0=1 on vblank or hblank, bit1=RS232in, bit3=1 on vblank, bit7=1 always, bit15:8=SD SPI byte read
|
85 |
|
|
write bit7=SD SPI MOSI bit, SPI CLK 0->1 (BYTE write only), bit8 = SD card chip select (WORD write only)
|
86 |
|
|
also reset the 3C0 port index flag
|
87 |
|
|
|
88 |
|
|
03B4, 03D4 - VGA CRT write index:
|
89 |
|
|
0A(bit 5 only): hide cursor
|
90 |
|
|
0C: HI screen offset
|
91 |
|
|
0D: LO screen offset
|
92 |
|
|
0E: HI cursor pos
|
93 |
|
|
0F: LO cursor pos
|
94 |
|
|
03B5, 03D5 - VGA CRT read/write data
|
95 |
|
|
*/
|
96 |
|
|
|
97 |
|
|
|
98 |
|
|
`timescale 1ns / 1ps
|
99 |
|
|
|
100 |
|
|
module system
|
101 |
|
|
(
|
102 |
|
|
inout [15:0]cntrl0_ddr2_dq,
|
103 |
|
|
output [12:0]cntrl0_ddr2_a,
|
104 |
|
|
output [1:0] cntrl0_ddr2_ba,
|
105 |
|
|
output cntrl0_ddr2_cke,
|
106 |
|
|
output cntrl0_ddr2_cs_n,
|
107 |
|
|
output cntrl0_ddr2_ras_n,
|
108 |
|
|
output cntrl0_ddr2_cas_n,
|
109 |
|
|
output cntrl0_ddr2_we_n,
|
110 |
|
|
output cntrl0_ddr2_odt,
|
111 |
|
|
output [1:0] cntrl0_ddr2_dm,
|
112 |
|
|
inout [1:0] cntrl0_ddr2_dqs,
|
113 |
|
|
inout [1:0] cntrl0_ddr2_dqs_n,
|
114 |
|
|
output cntrl0_ddr2_ck,
|
115 |
|
|
output cntrl0_ddr2_ck_n,
|
116 |
|
|
input cntrl0_rst_dqs_div_in,
|
117 |
|
|
output cntrl0_rst_dqs_div_out,
|
118 |
|
|
|
119 |
|
|
input sys_clk_in, // 133Mhz
|
120 |
|
|
input CLK_50MHZ,
|
121 |
|
|
|
122 |
|
|
output wire[3:0] VGA_R,
|
123 |
|
|
output wire[3:0] VGA_G,
|
124 |
|
|
output wire[3:0] VGA_B,
|
125 |
|
|
output wire VGA_HSYNC,
|
126 |
|
|
output wire VGA_VSYNC,
|
127 |
|
|
|
128 |
|
|
input BTN_SOUTH, // Reset
|
129 |
|
|
input BTN_WEST, // NMI
|
130 |
|
|
// output reg [7:0]LED,
|
131 |
|
|
output FPGA_AWAKE, // HALT
|
132 |
|
|
input RS232_DCE_RXD,
|
133 |
|
|
output reg RS232_DCE_TXD,
|
134 |
|
|
|
135 |
|
|
output reg SD_CS = 1,
|
136 |
|
|
output wire SD_DI,
|
137 |
|
|
output reg SD_CK = 0,
|
138 |
|
|
input SD_DO,
|
139 |
|
|
|
140 |
|
|
output AUD_L,
|
141 |
|
|
output AUD_R,
|
142 |
|
|
inout PS2_CLK1,
|
143 |
|
|
inout PS2_CLK2,
|
144 |
|
|
inout PS2_DATA1,
|
145 |
|
|
inout PS2_DATA2
|
146 |
|
|
);
|
147 |
|
|
|
148 |
|
|
wire [31:0]cntrl0_user_output_data;//o
|
149 |
|
|
wire [31:0]cntrl0_user_input_data;//i
|
150 |
|
|
wire [11:0]waddr;
|
151 |
|
|
wire [31:0] DOUT;
|
152 |
|
|
wire [15:0]CPU_DOUT;
|
153 |
|
|
wire [15:0]PORT_ADDR;
|
154 |
|
|
wire [31:0] DRAM_dout;
|
155 |
|
|
wire [31:0] SRAM_dout;
|
156 |
|
|
wire [19:0] ADDR;
|
157 |
|
|
wire IORQ;
|
158 |
|
|
wire WR;
|
159 |
|
|
wire INTA;
|
160 |
|
|
wire WORD;
|
161 |
|
|
wire [3:0] RAM_WMASK;
|
162 |
|
|
wire cntrl0_ar_done;
|
163 |
|
|
wire cntrl0_auto_ref_req;
|
164 |
|
|
wire cntrl0_user_cmd_ack;
|
165 |
|
|
wire cntrl0_user_data_valid;
|
166 |
|
|
wire cntrl0_sys_rst180_tb;
|
167 |
|
|
wire cntrl0_init_done;
|
168 |
|
|
wire hblnk;
|
169 |
|
|
wire vblnk;
|
170 |
|
|
wire [9:0]hcount;
|
171 |
|
|
wire [9:0]vcount;
|
172 |
|
|
wire displ_on = !(hblnk | vblnk);
|
173 |
|
|
wire [15:0]fifo_dout;
|
174 |
|
|
wire [11:0]DAC_COLOR;
|
175 |
|
|
wire fifo_empty; // fifo empty
|
176 |
|
|
wire full;
|
177 |
|
|
wire prog_full;
|
178 |
|
|
wire prog_empty;
|
179 |
|
|
wire clk_25;
|
180 |
|
|
wire clk_cpu;
|
181 |
|
|
wire CPU_CE; // CPU clock enable
|
182 |
|
|
wire CE;
|
183 |
|
|
wire ddr_rd;
|
184 |
|
|
wire ddr_wr;
|
185 |
|
|
wire TIMER_OE;
|
186 |
|
|
wire VGA_DAC_OE;
|
187 |
|
|
wire LED_PORT = PORT_ADDR[15:0] == 16'h03bc;
|
188 |
|
|
wire SPEAKER_PORT = PORT_ADDR[15:0] == 16'h0061;
|
189 |
|
|
wire MEMORY_MAP = PORT_ADDR[15:4] == 12'h008;
|
190 |
|
|
wire VGA_FONT_OE = PORT_ADDR[15:0] == 16'h03cb;
|
191 |
|
|
wire RS232_OE = PORT_ADDR[15:0] == 16'h0001;
|
192 |
|
|
wire INPUT_STATUS_OE = PORT_ADDR[15:0] == 16'h03da;
|
193 |
|
|
wire VGA_CRT_OE = (PORT_ADDR[15:1] == 15'b000000111011010) || (PORT_ADDR[15:1] == 15'b000000111101010); // 3b4, 3b5, 3d4, 3d5
|
194 |
|
|
wire RTC_SELECT = PORT_ADDR[15:0] == 16'h0070;
|
195 |
|
|
wire [7:0]VGA_DAC_DATA;
|
196 |
|
|
wire [7:0]VGA_CRT_DATA;
|
197 |
|
|
wire [15:0]PORT_IN;
|
198 |
|
|
wire [7:0]TIMER_DOUT;
|
199 |
|
|
wire [7:0]KB_DOUT;
|
200 |
|
|
wire [7:0]PIC_DOUT;
|
201 |
|
|
wire PIC_OE;
|
202 |
|
|
wire KB_OE;
|
203 |
|
|
|
204 |
|
|
reg [3:0]STATE = 0;
|
205 |
|
|
reg [1:0]cntrl0_user_command_register = 0;
|
206 |
|
|
reg cntrl0_burst_done = 0;
|
207 |
|
|
reg [15:0]vga_ddr_row_col = 0;// = 16'h4000; // video buffer at 0xa0000
|
208 |
|
|
reg [4:0]cache_counter = 0;
|
209 |
|
|
reg [5:0]lowaddr = 0; //cache mem address
|
210 |
|
|
reg s_prog_full;
|
211 |
|
|
reg s_prog_empty;
|
212 |
|
|
reg s_ddr_rd;
|
213 |
|
|
reg s_ddr_wr;
|
214 |
|
|
reg cache_op = 0;
|
215 |
|
|
reg [1:0]cww = 0; // cache write window
|
216 |
|
|
reg [3:0]crw = 0; // cache read window
|
217 |
|
|
reg crw_start = 0;
|
218 |
|
|
reg rfsh = 0;
|
219 |
|
|
wire ccd = cache_counter == 5'b11111;
|
220 |
|
|
reg s_RS232_DCE_RXD;
|
221 |
|
|
reg [4:0]rstcount = 0;
|
222 |
|
|
reg [1:0]s_displ_on = 0; // clk_25 delayed displ_on
|
223 |
|
|
reg [2:0]vga400 = 0; // 1 for 400 lines, 0 for 480 lines
|
224 |
|
|
reg [2:0]vgatext = 0; // 1 for text mode
|
225 |
|
|
wire vgaflash;
|
226 |
|
|
reg flashbit = 0;
|
227 |
|
|
reg [5:0]flashcount = 0;
|
228 |
|
|
reg s_ddr_endburst = 0;
|
229 |
|
|
wire [11:0]charcount = {vcount[8:4], 4'b0000} + {vcount[8:4], 6'b000000} + hcount[9:3];
|
230 |
|
|
|
231 |
|
|
reg [8:0]vga_ddr_row_count = 0;
|
232 |
|
|
reg [3:0]vga_repln_count = 0; // repeat line counter
|
233 |
|
|
reg [6:0]vga_lnbytecount = 0; // line byte count (multiple of 8)
|
234 |
|
|
reg [11:0]vga_font_counter = 0;
|
235 |
|
|
reg [7:0]vga_attr;
|
236 |
|
|
reg [4:0]RTCDIV25 = 0;
|
237 |
|
|
reg [1:0]RTCSYNC = 0;
|
238 |
|
|
reg [15:0]RTC = 0;
|
239 |
|
|
reg [15:0]RTCSET = 0;
|
240 |
|
|
wire RTCEND = RTC == RTCSET;
|
241 |
|
|
wire RTCDIVEND = RTCDIV25 == 24;
|
242 |
|
|
wire [11:0]cache_hi_addr = |cww ? waddr : ADDR[19:8];
|
243 |
|
|
wire [9:0]memmap;
|
244 |
|
|
wire [9:0]memmap_mux;
|
245 |
|
|
wire [3:0]vga_repln = vgatext[0] ? 15 : vga400[0] ? 1 : 0;
|
246 |
|
|
wire [6:0]vga_lnend = vgatext[0] ? 19 : vga400[0] ? 39 : 79; // multiple of 8(DDRAM resolution = 8)
|
247 |
|
|
wire vga_end_line = vga_lnbytecount == vga_lnend;
|
248 |
|
|
wire vga_repeat_line = vga_repln_count != vga_repln;
|
249 |
|
|
wire vga_end_frame = vga_ddr_row_count == (vgatext[0] | vga400[0] ? 399 : 479);
|
250 |
|
|
wire [7:0]font_dout;
|
251 |
|
|
wire [7:0]VGA_FONT_DATA;
|
252 |
|
|
wire [2:0]pxindex = -hcount[2:0];
|
253 |
|
|
wire vgatextreq;
|
254 |
|
|
wire vga400req;
|
255 |
|
|
wire oncursor;
|
256 |
|
|
wire [11:0]cursorpos;
|
257 |
|
|
wire [15:0]scraddr;
|
258 |
|
|
reg flash_on;
|
259 |
|
|
reg speaker_on = 0;
|
260 |
|
|
reg [9:0]rNMI = 0;
|
261 |
|
|
wire [3:0]VGA_MUX = (font_dout[pxindex] ^ flash_on) ? vga_attr[3:0] : {vga_attr[7] & ~vgaflash, vga_attr[6:4]};
|
262 |
|
|
|
263 |
|
|
wire [3:0]sdon = {4{s_displ_on[vgatext[1]]}};
|
264 |
|
|
assign VGA_R[3:0] = DAC_COLOR[3:0] & sdon;
|
265 |
|
|
assign VGA_G[3:0] = DAC_COLOR[7:4] & sdon;
|
266 |
|
|
assign VGA_B[3:0] = DAC_COLOR[11:8] & sdon;
|
267 |
|
|
|
268 |
|
|
// SD interface
|
269 |
|
|
reg [7:0]SDI;
|
270 |
|
|
assign SD_DI = CPU_DOUT[7];
|
271 |
|
|
|
272 |
|
|
assign PORT_IN[15:8] = { ({8{MEMORY_MAP}} & {6'b000000, memmap[9:8]}) |
|
273 |
|
|
({8{INPUT_STATUS_OE}} & SDI)
|
274 |
|
|
};
|
275 |
|
|
|
276 |
|
|
assign PORT_IN[7:0] = { ({8{VGA_DAC_OE}} & VGA_DAC_DATA) |
|
277 |
|
|
({8{VGA_FONT_OE}}& VGA_FONT_DATA) |
|
278 |
|
|
({8{KB_OE}} & KB_DOUT) |
|
279 |
|
|
({8{INPUT_STATUS_OE}} & {4'b1xxx, vblnk, 1'bx, s_RS232_DCE_RXD, hblnk | vblnk}) |
|
280 |
|
|
({8{VGA_CRT_OE}} & VGA_CRT_DATA) |
|
281 |
|
|
({8{MEMORY_MAP}} & {memmap[7:0]}) |
|
282 |
|
|
({8{TIMER_OE}} & TIMER_DOUT) |
|
283 |
|
|
({8{PIC_OE}} & PIC_DOUT)
|
284 |
|
|
};
|
285 |
|
|
|
286 |
|
|
dcm_vga dcm133_25
|
287 |
|
|
(
|
288 |
|
|
.CLKIN_IN(sys_clk_in),
|
289 |
|
|
.CLKFX_OUT(clk_25),
|
290 |
|
|
.CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT),
|
291 |
|
|
.CLK0_OUT(CLK0_OUT),
|
292 |
|
|
.CLK90_OUT(CLK90_OUT),
|
293 |
|
|
.LOCKED_OUT(LOCKED_OUT)
|
294 |
|
|
// .CLKDV_OUT(clk_cpu)
|
295 |
|
|
);
|
296 |
|
|
|
297 |
|
|
dcm_cpu dcm50_cpu
|
298 |
|
|
(
|
299 |
|
|
.CLKIN_IN(CLK_50MHZ),
|
300 |
|
|
.CLKFX_OUT(clk_cpu)
|
301 |
|
|
// .CLKDV_OUT(clk_25)
|
302 |
|
|
// .CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT),
|
303 |
|
|
// .CLK0_OUT(CLK0_OUT)
|
304 |
|
|
);
|
305 |
|
|
|
306 |
|
|
// ddr_cal_ctl.v, line 194, I made <tapfordqs> always fixed <default_tap> instead of variable <tapfordqs1>
|
307 |
|
|
// ddr_s3_dqs_iob.v, line 115, added delay property .IBUF_DELAY_VALUE("4") to IBUFDS (works ok for values < 8)
|
308 |
|
|
ddr u_ddr
|
309 |
|
|
(
|
310 |
|
|
.cntrl0_ddr2_dq (cntrl0_ddr2_dq),
|
311 |
|
|
.cntrl0_ddr2_a (cntrl0_ddr2_a),
|
312 |
|
|
.cntrl0_ddr2_ba (cntrl0_ddr2_ba),
|
313 |
|
|
.cntrl0_ddr2_cke (cntrl0_ddr2_cke),
|
314 |
|
|
.cntrl0_ddr2_cs_n (cntrl0_ddr2_cs_n),
|
315 |
|
|
.cntrl0_ddr2_ras_n (cntrl0_ddr2_ras_n),
|
316 |
|
|
.cntrl0_ddr2_cas_n (cntrl0_ddr2_cas_n),
|
317 |
|
|
.cntrl0_ddr2_we_n (cntrl0_ddr2_we_n),
|
318 |
|
|
.cntrl0_ddr2_odt (cntrl0_ddr2_odt),
|
319 |
|
|
.cntrl0_ddr2_dm (cntrl0_ddr2_dm),
|
320 |
|
|
.cntrl0_ddr2_dqs (cntrl0_ddr2_dqs),
|
321 |
|
|
.cntrl0_ddr2_dqs_n (cntrl0_ddr2_dqs_n),
|
322 |
|
|
.cntrl0_ddr2_ck (cntrl0_ddr2_ck),
|
323 |
|
|
.cntrl0_ddr2_ck_n (cntrl0_ddr2_ck_n),
|
324 |
|
|
.cntrl0_rst_dqs_div_in (cntrl0_rst_dqs_div_in),
|
325 |
|
|
.cntrl0_rst_dqs_div_out (cntrl0_rst_dqs_div_out),
|
326 |
|
|
|
327 |
|
|
.clk_int (CLK0_OUT),
|
328 |
|
|
.clk90_int (CLK90_OUT),
|
329 |
|
|
.dcm_lock (LOCKED_OUT),
|
330 |
|
|
|
331 |
|
|
.reset_in_n (1'b1),
|
332 |
|
|
.cntrl0_burst_done (cntrl0_burst_done),
|
333 |
|
|
.cntrl0_init_done (cntrl0_init_done),
|
334 |
|
|
.cntrl0_ar_done (cntrl0_ar_done),
|
335 |
|
|
.cntrl0_user_data_valid (cntrl0_user_data_valid),
|
336 |
|
|
.cntrl0_auto_ref_req (cntrl0_auto_ref_req),
|
337 |
|
|
.cntrl0_user_cmd_ack (cntrl0_user_cmd_ack),
|
338 |
|
|
.cntrl0_user_command_register ({cntrl0_user_command_register, 1'b0}),
|
339 |
|
|
.cntrl0_clk_tb (cntrl0_clk_tb),
|
340 |
|
|
.cntrl0_clk90_tb (cntrl0_clk90_tb),
|
341 |
|
|
// .cntrl0_sys_rst_tb (cntrl0_sys_rst_tb),
|
342 |
|
|
// .cntrl0_sys_rst90_tb (cntrl0_sys_rst90_tb),
|
343 |
|
|
.cntrl0_sys_rst180_tb (cntrl0_sys_rst180_tb),
|
344 |
|
|
.cntrl0_user_output_data (cntrl0_user_output_data),
|
345 |
|
|
.cntrl0_user_input_data (cntrl0_user_input_data),
|
346 |
|
|
.cntrl0_user_data_mask (4'b0000),
|
347 |
|
|
.cntrl0_user_input_address (cache_op ? {memmap_mux[9:6], memmap_mux[3:0], cache_hi_addr[7:0], cache_counter, 2'b00, memmap_mux[5:4]}: {5'b00001, vga_ddr_row_col, 2'b00, 2'b00})
|
348 |
|
|
);
|
349 |
|
|
|
350 |
|
|
fifo ddr_vga_fifo
|
351 |
|
|
(
|
352 |
|
|
.rst(cntrl0_sys_rst180_tb), // input rst
|
353 |
|
|
.wr_clk(cntrl0_clk90_tb), // input wr_clk
|
354 |
|
|
.rd_clk(clk_25), // input rd_clk
|
355 |
|
|
.din({cntrl0_user_output_data[7:0], cntrl0_user_output_data[15:8], cntrl0_user_output_data[23:16], cntrl0_user_output_data[31:24]}), // input [31 : 0] din
|
356 |
|
|
.wr_en(~crw[3] && cntrl0_user_data_valid),
|
357 |
|
|
.rd_en(!fifo_empty && displ_on && (vgatext[1] ? &hcount[2:0] : vga400[1] ? &hcount[1:0] : hcount[0])), // input rd_en
|
358 |
|
|
.dout(fifo_dout), // output [15 : 0] dout
|
359 |
|
|
.full(full), // output full
|
360 |
|
|
.empty(fifo_empty), // output empty
|
361 |
|
|
.prog_full(prog_full), // output prog_full
|
362 |
|
|
.prog_empty(prog_empty) // output prog_empty
|
363 |
|
|
);
|
364 |
|
|
|
365 |
|
|
VGA_SG VGA
|
366 |
|
|
(
|
367 |
|
|
.tc_hsblnk(10'd639),
|
368 |
|
|
.tc_hssync(10'd655),
|
369 |
|
|
.tc_hesync(10'd751),
|
370 |
|
|
.tc_heblnk(10'd799),
|
371 |
|
|
.hcount(hcount),
|
372 |
|
|
.hsync(VGA_HSYNC),
|
373 |
|
|
.hblnk(hblnk),
|
374 |
|
|
.tc_vsblnk(vga400[2] | vgatext[2] ? 10'd399 : 10'd479),
|
375 |
|
|
.tc_vssync(vga400[2] | vgatext[2] ? 10'd411 : 10'd489),
|
376 |
|
|
.tc_vesync(vga400[2] | vgatext[2] ? 10'd413 : 10'd491),
|
377 |
|
|
.tc_veblnk(vga400[2] | vgatext[2] ? 10'd446 : 10'd520),
|
378 |
|
|
.vcount(vcount),
|
379 |
|
|
.vsync(VGA_VSYNC),
|
380 |
|
|
.vblnk(vblnk),
|
381 |
|
|
.clk(clk_25),
|
382 |
|
|
.ce(!fifo_empty)
|
383 |
|
|
);
|
384 |
|
|
|
385 |
|
|
VGA_DAC dac
|
386 |
|
|
(
|
387 |
|
|
.CE(IORQ && CPU_CE && (PORT_ADDR[15:4] == 12'h03c)),
|
388 |
|
|
.WR(WR),
|
389 |
|
|
.addr(PORT_ADDR[3:0]),
|
390 |
|
|
.din(CPU_DOUT[7:0]),
|
391 |
|
|
.OE(VGA_DAC_OE),
|
392 |
|
|
.dout(VGA_DAC_DATA),
|
393 |
|
|
.CLK(clk_cpu),
|
394 |
|
|
.VGA_CLK(clk_25),
|
395 |
|
|
.vga_addr(vgatext[1] ? {4'b0000, VGA_MUX} : (vga400[1] ? hcount[1] : hcount[0]) ? fifo_dout[7:0] : fifo_dout[15:8]),
|
396 |
|
|
.color(DAC_COLOR),
|
397 |
|
|
.vgatext(vgatextreq),
|
398 |
|
|
.vga400(vga400req),
|
399 |
|
|
.vgaflash(vgaflash),
|
400 |
|
|
.setindex(INPUT_STATUS_OE && IORQ && CPU_CE)
|
401 |
|
|
);
|
402 |
|
|
|
403 |
|
|
VGA_CRT crt
|
404 |
|
|
(
|
405 |
|
|
.CE(IORQ && CPU_CE && VGA_CRT_OE),
|
406 |
|
|
.WR(WR),
|
407 |
|
|
.din(CPU_DOUT[7:0]),
|
408 |
|
|
.addr(PORT_ADDR[0]),
|
409 |
|
|
.dout(VGA_CRT_DATA),
|
410 |
|
|
.CLK(clk_cpu),
|
411 |
|
|
.oncursor(oncursor),
|
412 |
|
|
.cursorpos(cursorpos),
|
413 |
|
|
.scraddr(scraddr)
|
414 |
|
|
);
|
415 |
|
|
|
416 |
|
|
sr_font VGA_FONT
|
417 |
|
|
(
|
418 |
|
|
.clka(clk_25), // input clka
|
419 |
|
|
.wea(1'b0), // input [0 : 0] wea
|
420 |
|
|
.addra({fifo_dout[15:8], vcount[3:0]}), // input [11 : 0] addra
|
421 |
|
|
.dina(8'hxx), // input [7 : 0] dina
|
422 |
|
|
.douta(font_dout), // output [7 : 0] douta
|
423 |
|
|
.clkb(clk_cpu), // input clkb
|
424 |
|
|
.web(CPU_CE & WR & IORQ & VGA_FONT_OE & ~WORD), // input [0 : 0] web
|
425 |
|
|
.addrb(vga_font_counter), // input [11 : 0] addrb
|
426 |
|
|
.dinb(CPU_DOUT[7:0]), // input [7 : 0] dinb
|
427 |
|
|
.doutb(VGA_FONT_DATA) // output [7 : 0] doutb
|
428 |
|
|
);
|
429 |
|
|
|
430 |
|
|
cache_controller cache_ctl
|
431 |
|
|
(
|
432 |
|
|
.addr(ADDR),
|
433 |
|
|
.dout(DRAM_dout),
|
434 |
|
|
.din(DOUT),
|
435 |
|
|
.clk(clk_cpu),
|
436 |
|
|
.mreq(MREQ),
|
437 |
|
|
.wr(WR),
|
438 |
|
|
.wmask(RAM_WMASK),
|
439 |
|
|
.ce(CE),
|
440 |
|
|
.ddr_din(cntrl0_user_output_data),
|
441 |
|
|
.ddr_dout(cntrl0_user_input_data),
|
442 |
|
|
.ddr_clk(cntrl0_clk90_tb),
|
443 |
|
|
.ddr_rd(ddr_rd),
|
444 |
|
|
.ddr_wr(ddr_wr),
|
445 |
|
|
.lowaddr(lowaddr),
|
446 |
|
|
.waddr(waddr),
|
447 |
|
|
.cache_write_data(crw[3] && cntrl0_user_data_valid) // read DDR, write to cache
|
448 |
|
|
);
|
449 |
|
|
|
450 |
|
|
wire I_KB;
|
451 |
|
|
wire I_MOUSE;
|
452 |
|
|
wire KB_RST;
|
453 |
|
|
KB_Mouse_8042 KB_Mouse
|
454 |
|
|
(
|
455 |
|
|
.CS(IORQ && CPU_CE && PORT_ADDR[15:4] == 12'h006 && {PORT_ADDR[3], PORT_ADDR[1:0]} == 3'b000), // 60h, 64h
|
456 |
|
|
.WR(WR),
|
457 |
|
|
.cmd(PORT_ADDR[2]), // 64h
|
458 |
|
|
.din(CPU_DOUT[7:0]),
|
459 |
|
|
.OE(KB_OE),
|
460 |
|
|
.dout(KB_DOUT),
|
461 |
|
|
.clk(clk_cpu),
|
462 |
|
|
.I_KB(I_KB),
|
463 |
|
|
.I_MOUSE(I_MOUSE),
|
464 |
|
|
.CPU_RST(KB_RST),
|
465 |
|
|
.PS2_CLK1(PS2_CLK1),
|
466 |
|
|
.PS2_CLK2(PS2_CLK2),
|
467 |
|
|
.PS2_DATA1(PS2_DATA1),
|
468 |
|
|
.PS2_DATA2(PS2_DATA2)
|
469 |
|
|
);
|
470 |
|
|
|
471 |
|
|
wire [7:0]PIC_IVECT;
|
472 |
|
|
wire INT;
|
473 |
|
|
wire timer_int;
|
474 |
|
|
PIC_8259 PIC
|
475 |
|
|
(
|
476 |
|
|
.CS((PORT_ADDR[15:8] == 8'h00) && (PORT_ADDR[6:0] == 7'b0100001) && IORQ && CPU_CE), // 21h, a1h
|
477 |
|
|
.WR(WR),
|
478 |
|
|
.din(CPU_DOUT[7:0]),
|
479 |
|
|
.OE(PIC_OE),
|
480 |
|
|
.dout(PIC_DOUT),
|
481 |
|
|
.ivect(PIC_IVECT),
|
482 |
|
|
.clk(clk_cpu),
|
483 |
|
|
.INT(INT),
|
484 |
|
|
.IACK(INTA & CPU_CE),
|
485 |
|
|
.I({I_MOUSE, RTCEND, I_KB, timer_int})
|
486 |
|
|
// .I({hblnk, 1'b0, vblnk, timer_int})
|
487 |
|
|
);
|
488 |
|
|
|
489 |
|
|
unit186 CPUUnit
|
490 |
|
|
(
|
491 |
|
|
.INPORT(INTA ? PIC_IVECT : PORT_IN),
|
492 |
|
|
.DIN(DRAM_dout),
|
493 |
|
|
.CPU_DOUT(CPU_DOUT),
|
494 |
|
|
.PORT_ADDR(PORT_ADDR),
|
495 |
|
|
.DOUT(DOUT),
|
496 |
|
|
.ADDR(ADDR),
|
497 |
|
|
.WMASK(RAM_WMASK),
|
498 |
|
|
.CLK(clk_cpu),
|
499 |
|
|
.CE(CE),
|
500 |
|
|
.CPU_CE(CPU_CE),
|
501 |
|
|
.INTR(INT),
|
502 |
|
|
.NMI(rNMI[9]),
|
503 |
|
|
.RST(BTN_SOUTH || !rstcount[4]),
|
504 |
|
|
.INTA(INTA),
|
505 |
|
|
// .LOCK(LOCK),
|
506 |
|
|
.HALT(FPGA_AWAKE),
|
507 |
|
|
.MREQ(MREQ),
|
508 |
|
|
.IORQ(IORQ),
|
509 |
|
|
.WR(WR),
|
510 |
|
|
.WORD(WORD)
|
511 |
|
|
);
|
512 |
|
|
|
513 |
|
|
seg_map seg_mapper
|
514 |
|
|
(
|
515 |
|
|
.CLK(clk_cpu),
|
516 |
|
|
.addr(PORT_ADDR[3:0]),
|
517 |
|
|
.rdata(memmap),
|
518 |
|
|
.wdata(CPU_DOUT[9:0]),
|
519 |
|
|
.addr1(cache_hi_addr[11:8]),
|
520 |
|
|
.data1(memmap_mux),
|
521 |
|
|
.WE(MEMORY_MAP & WR & WORD & IORQ & CPU_CE)
|
522 |
|
|
);
|
523 |
|
|
|
524 |
|
|
wire timer_spk;
|
525 |
|
|
timer_8253 timer
|
526 |
|
|
(
|
527 |
|
|
.CS(PORT_ADDR[15:2] == 14'b00000000010000 && IORQ && CPU_CE),
|
528 |
|
|
.WR(WR),
|
529 |
|
|
.addr(PORT_ADDR[1:0]),
|
530 |
|
|
.din(CPU_DOUT[7:0]),
|
531 |
|
|
.OE(TIMER_OE),
|
532 |
|
|
.dout(TIMER_DOUT),
|
533 |
|
|
.CLK_25(clk_25),
|
534 |
|
|
.clk(clk_cpu),
|
535 |
|
|
.out0(timer_int),
|
536 |
|
|
.out2(timer_spk)
|
537 |
|
|
);
|
538 |
|
|
assign AUD_L = speaker_on & timer_spk;
|
539 |
|
|
assign AUD_R = speaker_on & timer_spk;
|
540 |
|
|
|
541 |
|
|
always @ (negedge cntrl0_clk_tb) begin
|
542 |
|
|
cntrl0_user_command_register <= 2'b00;
|
543 |
|
|
cntrl0_burst_done <= 1'b0;
|
544 |
|
|
s_prog_full <= prog_full; // sychronized because prog_full is asserted on a different clock
|
545 |
|
|
s_prog_empty <= prog_empty;
|
546 |
|
|
s_ddr_rd <= ddr_rd;
|
547 |
|
|
s_ddr_wr <= ddr_wr;
|
548 |
|
|
s_ddr_endburst <= s_prog_full || cntrl0_auto_ref_req || (~s_prog_empty && (s_ddr_rd || s_ddr_wr));
|
549 |
|
|
crw_start <= 1'b0;
|
550 |
|
|
cww[1] <= cww[0];
|
551 |
|
|
if(cntrl0_auto_ref_req) rfsh <= 1'b1;
|
552 |
|
|
else if(cntrl0_ar_done) rfsh <= 1'b0;
|
553 |
|
|
|
554 |
|
|
if(cntrl0_sys_rst180_tb) begin
|
555 |
|
|
STATE <= 4'b0000;
|
556 |
|
|
vga_ddr_row_col <= 0;
|
557 |
|
|
vga_ddr_row_count <= 0;
|
558 |
|
|
cache_counter <= 0;
|
559 |
|
|
vga_repln_count <= 0;
|
560 |
|
|
vga_lnbytecount <= 0;
|
561 |
|
|
end else case(STATE)
|
562 |
|
|
4'b0000: begin
|
563 |
|
|
cntrl0_user_command_register <= 2'b01; // initialize DDR
|
564 |
|
|
STATE <= 4'b0001; // reset
|
565 |
|
|
end
|
566 |
|
|
|
567 |
|
|
// wait for completion
|
568 |
|
|
4'b0001: begin
|
569 |
|
|
if(~cntrl0_user_cmd_ack && cntrl0_init_done && ~rfsh && ~cntrl0_auto_ref_req) begin
|
570 |
|
|
if(s_prog_empty) begin
|
571 |
|
|
cntrl0_user_command_register <= 2'b11;
|
572 |
|
|
STATE <= 4'b0010;
|
573 |
|
|
end else if(s_ddr_wr) begin
|
574 |
|
|
cntrl0_user_command_register <= 2'b10;
|
575 |
|
|
cache_op <= 1'b1;
|
576 |
|
|
cww[0] <= 1'b1;
|
577 |
|
|
STATE <= 4'b0110;
|
578 |
|
|
end else if(s_ddr_rd) begin
|
579 |
|
|
cntrl0_user_command_register <= 2'b11;
|
580 |
|
|
cache_op <= 1'b1;
|
581 |
|
|
STATE <= 4'b1010;
|
582 |
|
|
end else if(~s_prog_full) begin
|
583 |
|
|
cntrl0_user_command_register <= 2'b11;
|
584 |
|
|
STATE <= 4'b0010;
|
585 |
|
|
end
|
586 |
|
|
end
|
587 |
|
|
end
|
588 |
|
|
|
589 |
|
|
// VGA read
|
590 |
|
|
4'b0010: begin // assert READ command, wait for ACK
|
591 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
592 |
|
|
if(cntrl0_user_cmd_ack) STATE <= 4'b0011;
|
593 |
|
|
end
|
594 |
|
|
4'b0011: begin // keep READ for 2nd T after ACK
|
595 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
596 |
|
|
STATE <= 4'b0100;
|
597 |
|
|
end
|
598 |
|
|
4'b0100: begin // keep READ for 3rd T after ACK
|
599 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
600 |
|
|
|
601 |
|
|
if(vga_end_line) begin
|
602 |
|
|
vga_lnbytecount <= 0;
|
603 |
|
|
vga_ddr_row_count <= vga_ddr_row_count + 1;
|
604 |
|
|
if(vga_repeat_line) begin
|
605 |
|
|
vga_repln_count <= vga_repln_count + 1;
|
606 |
|
|
vga_ddr_row_col <= vga_ddr_row_col - vga_lnend;
|
607 |
|
|
end else begin
|
608 |
|
|
vga_repln_count <= 0;
|
609 |
|
|
if(vga_end_frame) begin
|
610 |
|
|
vga400[0] <= vga400req;
|
611 |
|
|
vgatext[0] <= vgatextreq;
|
612 |
|
|
vga_ddr_row_col <= scraddr + {vgatext[0] ? 4'b0111 : 4'b0100, 12'h000};
|
613 |
|
|
vga_ddr_row_count <= 0;
|
614 |
|
|
end else vga_ddr_row_col <= vga_ddr_row_col + 1;
|
615 |
|
|
end
|
616 |
|
|
end else begin
|
617 |
|
|
vga_lnbytecount <= vga_lnbytecount + 1;
|
618 |
|
|
vga_ddr_row_col <= vga_ddr_row_col + 1;
|
619 |
|
|
end
|
620 |
|
|
|
621 |
|
|
// vga_ddr_row_col <= vga_ddr_row_col == vga_ddr_row_col_end ? vga_ddr_row_col_start : vga_ddr_row_col + 1;
|
622 |
|
|
if(s_ddr_endburst || &vga_ddr_row_col[7:0] || ((vga_end_frame || vga_repeat_line) && vga_end_line)) begin // end burst if (FIFO full or DDR refresh or end column address)
|
623 |
|
|
cntrl0_burst_done <= 1'b1;
|
624 |
|
|
STATE <= 4'b0101; // end burst
|
625 |
|
|
end else STATE <= 4'b0011; // continue read burst
|
626 |
|
|
end
|
627 |
|
|
4'b0101: begin // keep burst_done
|
628 |
|
|
cntrl0_burst_done <= 1'b1;
|
629 |
|
|
cache_op <= 1'b0;
|
630 |
|
|
STATE <= 4'b0001;
|
631 |
|
|
end
|
632 |
|
|
|
633 |
|
|
// cache write to DDR
|
634 |
|
|
4'b0110: begin // assert WRITE command, wait for ACK
|
635 |
|
|
cntrl0_user_command_register <= 2'b10; // write
|
636 |
|
|
if(cntrl0_user_cmd_ack) STATE <= 4'b0111;
|
637 |
|
|
end
|
638 |
|
|
4'b0111: begin // keep WRITE for 2nd T after ACK
|
639 |
|
|
cntrl0_user_command_register <= 2'b10; // write
|
640 |
|
|
if(cntrl0_auto_ref_req || ccd) cww[0] <= 1'b0;
|
641 |
|
|
STATE <= 4'b1000;
|
642 |
|
|
end
|
643 |
|
|
4'b1000: begin // keep WRITE for 3rd T after ACK
|
644 |
|
|
cntrl0_user_command_register <= 2'b10; // write
|
645 |
|
|
cache_counter <= cache_counter + 1;
|
646 |
|
|
if(~cww[0]) begin
|
647 |
|
|
cntrl0_burst_done <= 1'b1;
|
648 |
|
|
STATE <= ccd ? 4'b0101 : 4'b1001;
|
649 |
|
|
end else STATE <= 4'b0111;
|
650 |
|
|
end
|
651 |
|
|
4'b1001: begin
|
652 |
|
|
cntrl0_burst_done <= 1'b1;
|
653 |
|
|
STATE <= 4'b1110;
|
654 |
|
|
end
|
655 |
|
|
4'b1110: begin
|
656 |
|
|
if(~cntrl0_user_cmd_ack) begin
|
657 |
|
|
cntrl0_user_command_register <= 2'b10; // write
|
658 |
|
|
cww[0] <= 1'b1;
|
659 |
|
|
STATE <= 4'b0110;
|
660 |
|
|
end
|
661 |
|
|
end
|
662 |
|
|
|
663 |
|
|
// cache read from DDR
|
664 |
|
|
4'b1010: begin // assert READ command, wait for ACK
|
665 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
666 |
|
|
if(cntrl0_user_cmd_ack) STATE <= 4'b1011;
|
667 |
|
|
end
|
668 |
|
|
4'b1011: begin // keep READ for 2nd T after ACK
|
669 |
|
|
crw_start <= 1'b1;
|
670 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
671 |
|
|
STATE <= 4'b1100;
|
672 |
|
|
end
|
673 |
|
|
4'b1100: begin // keep READ for 3rd T after ACK
|
674 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
675 |
|
|
cache_counter <= cache_counter + 1;
|
676 |
|
|
if(cntrl0_auto_ref_req || ccd) begin
|
677 |
|
|
cntrl0_burst_done <= 1'b1;
|
678 |
|
|
STATE <= ccd ? 4'b0101 : 4'b1101;
|
679 |
|
|
end else STATE <= 4'b1011;
|
680 |
|
|
end
|
681 |
|
|
4'b1101: begin // keep burst_done
|
682 |
|
|
cntrl0_burst_done <= 1'b1;
|
683 |
|
|
STATE <= 4'b1111;
|
684 |
|
|
end
|
685 |
|
|
4'b1111: begin
|
686 |
|
|
if(~cntrl0_user_cmd_ack) begin
|
687 |
|
|
cntrl0_user_command_register <= 2'b11; // read
|
688 |
|
|
STATE <= 4'b1010;
|
689 |
|
|
end
|
690 |
|
|
end
|
691 |
|
|
|
692 |
|
|
endcase
|
693 |
|
|
end
|
694 |
|
|
|
695 |
|
|
|
696 |
|
|
always @ (posedge cntrl0_clk90_tb) begin
|
697 |
|
|
if(cntrl0_sys_rst180_tb) begin
|
698 |
|
|
crw <= 0;
|
699 |
|
|
lowaddr <= 0;
|
700 |
|
|
end else begin
|
701 |
|
|
if((crw[3] && cntrl0_user_data_valid) || (cww[0] && cntrl0_user_cmd_ack)) lowaddr <= lowaddr + 1;
|
702 |
|
|
if(~crw[3]) begin
|
703 |
|
|
if(crw_start || |crw[2:0]) crw <= crw + 1;
|
704 |
|
|
end else if(&lowaddr) crw <= 0;
|
705 |
|
|
end
|
706 |
|
|
end
|
707 |
|
|
|
708 |
|
|
always @ (posedge clk_cpu) begin
|
709 |
|
|
s_RS232_DCE_RXD <= RS232_DCE_RXD;
|
710 |
|
|
if(IORQ & CPU_CE) begin
|
711 |
|
|
if(WR & RS232_OE) RS232_DCE_TXD <= CPU_DOUT[0];
|
712 |
|
|
if(VGA_FONT_OE) vga_font_counter <= WR && WORD ? {CPU_DOUT[7:0], 4'b0000} : vga_font_counter + 1;
|
713 |
|
|
if(WR & SPEAKER_PORT) speaker_on <= &CPU_DOUT[1:0];
|
714 |
|
|
// if(WR & LED_PORT) LED <= CPU_DOUT[7:0];
|
715 |
|
|
end
|
716 |
|
|
// SD
|
717 |
|
|
if(CPU_CE) begin
|
718 |
|
|
SD_CK <= IORQ & INPUT_STATUS_OE & WR & ~WORD;
|
719 |
|
|
if(IORQ & INPUT_STATUS_OE & WR) begin
|
720 |
|
|
if(WORD) SD_CS <= ~CPU_DOUT[8]; // SD chip select
|
721 |
|
|
else SDI <= {SDI[6:0], SD_DO};
|
722 |
|
|
end
|
723 |
|
|
end
|
724 |
|
|
|
725 |
|
|
if(KB_RST) rstcount <= 0;
|
726 |
|
|
else if(CPU_CE && ~rstcount[4]) rstcount <= rstcount + 1;
|
727 |
|
|
|
728 |
|
|
// RTC
|
729 |
|
|
RTCSYNC <= {RTCSYNC[0], RTCDIVEND};
|
730 |
|
|
if(IORQ && CPU_CE && WR && WORD && RTC_SELECT) begin
|
731 |
|
|
RTC <= 0;
|
732 |
|
|
RTCSET <= CPU_DOUT;
|
733 |
|
|
end else if(RTCSYNC == 2'b01) begin
|
734 |
|
|
if(RTCEND) RTC <= 0;
|
735 |
|
|
else RTC <= RTC + 1;
|
736 |
|
|
end
|
737 |
|
|
|
738 |
|
|
end
|
739 |
|
|
|
740 |
|
|
always @ (posedge clk_25) begin
|
741 |
|
|
s_displ_on[1:0] <= {s_displ_on[0], displ_on};
|
742 |
|
|
vga_attr <= fifo_dout[7:0];
|
743 |
|
|
|
744 |
|
|
flash_on <= (vgaflash & fifo_dout[7] & flashcount[5]) | (~oncursor && flashcount[4] && (charcount == cursorpos) && ((vcount[3:0] == 13) || vcount[3:0] == 14));
|
745 |
|
|
|
746 |
|
|
if(!vblnk) begin
|
747 |
|
|
flashbit <= 1;
|
748 |
|
|
vga400[2] <= vga400[1];
|
749 |
|
|
vgatext[2] <= vgatext[1];
|
750 |
|
|
end else if(flashbit) begin
|
751 |
|
|
flashcount <= flashcount + 1;
|
752 |
|
|
flashbit <= 0;
|
753 |
|
|
vga400[1] <= vga400[0];
|
754 |
|
|
vgatext[1] <= vgatext[0];
|
755 |
|
|
end
|
756 |
|
|
|
757 |
|
|
if(RTCDIVEND) RTCDIV25 <= 0; // real time clock
|
758 |
|
|
else RTCDIV25 <= RTCDIV25 + 1;
|
759 |
|
|
|
760 |
|
|
if(!BTN_WEST) rNMI <= 0; // NMI
|
761 |
|
|
else if(!rNMI[9] && RTCDIVEND) rNMI <= rNMI + 1; // 1Mhz increment
|
762 |
|
|
|
763 |
|
|
end
|
764 |
|
|
|
765 |
|
|
endmodule
|
766 |
|
|
|