2 // Copyright (C) 2008 Tomasz Malesinski <tmal@mimuw.edu.pl>
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 module pokey_counter(clk_i
, dat_i
,
19 freq_ld
, start
, cnt_en
,
22 input freq_ld
, start
, cnt_en
;
28 wire freq_ld
, start
, cnt_en
;
33 assign borrow
= (out
== 0);
35 always @ (posedge clk_i
)
41 always @ (posedge clk_i
)
47 module pokey_basefreq(rst
, clk_i
, base15
, out
);
48 input rst
, clk_i
, base15
;
51 wire rst
, clk_i
, base15
;
52 wire out
= (div57
== 0) && (!base15 || div4
== 0);
57 always @ (posedge clk_i
)
61 end else if (div57
== 56) begin
68 module pokey_poly4(rst
, clk_i
, out
);
77 always @ (posedge clk_i
)
79 shift
<= {shift
[2:0], 1'b0};
81 shift
<= {shift
[2:0], shift
[3] ~^ shift
[2]};
84 module pokey_poly5(rst
, clk_i
, out
);
93 always @ (posedge clk_i
)
95 shift
<= {shift
[3:0], 1'b0};
97 shift
<= {shift
[3:0], shift
[4] ~^ shift
[2]};
100 module pokey_poly17(rst
, clk_i
, short
, out
, random
);
101 input rst
, clk_i
, short
;
105 wire out
= shift
[16];
106 wire [7:0] random
= shift
[16:9];
109 wire new_bit
= shift
[16] ~^ shift
[11];
112 // last_short is used to reset the shortened shift register when
113 // shwitching from long to short.
114 always @ (posedge clk_i
)
117 always @ (posedge clk_i
)
118 shift
<= {shift
[15:8],
119 (short ? new_bit
: shift
[7]) & ~rst
& (last_short |
~short
),
120 shift
[6:0], new_bit
};
123 module pokey_audout(rst
, clk_i
, dat_i
,
125 poly4
, poly5
, poly17
,
126 in
, filter_en
, filter_in
,
128 input rst
, clk_i
, dat_i
;
130 input poly4
, poly5
, poly17
;
131 input in
, filter_en
, filter_in
;
138 wire poly4
, poly5
, poly17
;
139 wire in
, filter_en
, filter_in
;
141 wire [3:0] out
= (ch_out | vol_only
) ? vol
: 0;
151 wire change
= in
& (no_poly5 | poly5
);
152 wire ch_out
= filter_en ? filter_reg ^ nf
: nf
;
154 always @ (posedge clk_i
)
157 vol_only
<= dat_i
[4];
158 no_poly5
<= dat_i
[7];
159 poly4_sel
<= dat_i
[6];
160 no_poly17_4
<= dat_i
[5];
163 always @ (posedge clk_i
)
174 always @ (posedge clk_i
)
175 if (!filter_en || rst
)
181 module pokey(rst_i
, clk_i
,
190 key_code
, key_pressed
, key_shift
, key_break
);
197 input key_code
, key_pressed
, key_shift
, key_break
;
210 wire key_pressed
, key_shift
, key_break
;
211 reg last_key_pressed
, last_key_break
;
216 wire [5:0] audout
= audout0
+ audout1
+ audout2
+ audout3
;
218 wire rst
= (rst_bits
== 0);
223 parameter [2:0] IRQ_BREAK
= 7;
224 parameter [2:0] IRQ_KEY
= 6;
225 parameter [2:0] IRQ_SERIN
= 5;
226 parameter [2:0] IRQ_SEROUT
= 4;
227 parameter [2:0] IRQ_SERFIN
= 3;
228 parameter [2:0] IRQ_TIMER4
= 2;
229 parameter [2:0] IRQ_TIMER2
= 1;
230 parameter [2:0] IRQ_TIMER1
= 1;
255 wire poly4
, poly5
, poly17
;
256 reg [3:1] poly4_shift
, poly5_shift
, poly17_shift
;
259 wire [3:0] audout0
, audout1
, audout2
, audout3
;
265 assign ack_o
= stb_i
;
267 always @ (adr_i
or random
)
271 else if (adr_i
== 'ha
)
274 else if (adr_i
== 'hd
)
277 else if (adr_i
== 'he
)
279 dat_o
= ~(irqst
& irqen
);
280 else if (adr_i
== 'hf
)
282 dat_o
= {1'b1, // no framing error
283 1'b1, // no keyboard overrun
284 1'b1, // no serial data input over-run
285 1'b1, // serial input pad
288 1'b1, // serial input shift register busy
293 always @ (we_i
or stb_i
or adr_i
) begin
294 for (i
= 0; i
< 4; i
= i
+ 1)
295 audf_we
[i
] = (adr_i
== (i
<< 1));
296 for (i
= 0; i
< 4; i
= i
+ 1)
297 audc_we
[i
] = (adr_i
== ((i
<< 1) + 1));
300 assign start_timer
= (we_i
&& stb_i
&& adr_i
== 9);
302 always @ (posedge clk_i
)
303 if (we_i
&& stb_i
&& adr_i
== 8) begin
305 fast_ch0
<= dat_i
[6];
306 fast_ch2
<= dat_i
[5];
315 always @ (posedge clk_i
)
316 if (we_i
&& stb_i
&& adr_i
== 'ha
) begin
317 // TODO: reset SKSTAT[7:5] if they are implemented
321 always @ (posedge clk_i
)
322 if (we_i
&& stb_i
&& adr_i
== 'hd
) begin
323 // TODO: serial output
327 always @ (posedge clk_i
)
328 if (we_i
&& stb_i
&& adr_i
== 'he
)
331 always @ (posedge clk_i
)
332 if (we_i
&& stb_i
&& adr_i
== 'hf
) begin
333 rst_bits
<= dat_i
[1:0];
334 // TODO: rest of the bits.
337 always @ (posedge clk_i
) begin
338 last_key_pressed
<= key_pressed
;
339 last_key_break
<= key_break
;
342 always @ (posedge clk_i
)
343 // IRQ_SERFIN has no latch.
344 irqst
<= irqen
& ({irqst
[7:4], 1'b0, irqst
[2:0]} |
345 {key_break
&& !last_key_break
,
346 key_pressed
&& !last_key_pressed
,
347 3'b000, borrow
[3], borrow
[1:0]});
349 always @ (irqst
) begin
351 for (i
= 0; i
< 8; i
= i
+ 1)
352 irq
= irq || irqst
[i
];
355 pokey_basefreq
u_base(rst
, clk_i
, base15
, base
);
357 pokey_poly4
u_poly4(rst
, clk_i
, poly4
);
358 pokey_poly5
u_poly5(rst
, clk_i
, poly5
);
359 pokey_poly17
u_poly17(rst
, clk_i
, poly9
, poly17
, random
);
361 always @ (posedge clk_i
) begin
362 poly4_shift
<= {poly4_shift
[2:1], poly4
};
363 poly5_shift
<= {poly5_shift
[2:1], poly5
};
364 poly17_shift
<= {poly17_shift
[2:1], poly17
};
367 assign cnt_en
[0] = fast_ch0 ?
1 : base
;
368 assign cnt_en
[1] = ch01 ? borrow
[0] : base
;
369 assign cnt_en
[2] = fast_ch2 ?
1 : base
;
370 assign cnt_en
[3] = ch23 ? borrow
[2] : base
;
372 assign start
[0] = start_timer |
(ch01 ? borrow
[1] : borrow
[0]);
373 assign start
[1] = start_timer | borrow
[1];
374 assign start
[2] = start_timer |
(ch23 ? borrow
[3] : borrow
[2]);
375 assign start
[3] = start_timer | borrow
[3];
377 // TODO: clean it up after removing the array of instances
378 // (remove assignments above)
379 // TODO: do we need ctr_out?
380 pokey_counter
u_ctr0(clk_i
, dat_i
,
381 audf_we
[0], start
[0], cnt_en
[0],
382 ctr_out
[7:0], borrow
[0]);
383 pokey_counter
u_ctr1(clk_i
, dat_i
,
384 audf_we
[1], start
[1], cnt_en
[1],
385 ctr_out
[15:8], borrow
[1]);
386 pokey_counter
u_ctr2(clk_i
, dat_i
,
387 audf_we
[2], start
[2], cnt_en
[2],
388 ctr_out
[23:16], borrow
[2]);
389 pokey_counter
u_ctr3(clk_i
, dat_i
,
390 audf_we
[3], start
[3], cnt_en
[3],
391 ctr_out
[31:24], borrow
[3]);
392 pokey_audout
u_audout0(start_timer
, clk_i
, dat_i
,
394 poly4
, poly5
, poly17
,
395 borrow
[0], fi02
, borrow
[2],
397 pokey_audout
u_audout1(start_timer
, clk_i
, dat_i
,
399 poly4_shift
[1], poly5_shift
[1], poly17_shift
[1],
400 borrow
[1], fi13
, borrow
[3],
402 pokey_audout
u_audout2(start_timer
, clk_i
, dat_i
,
404 poly4_shift
[2], poly5_shift
[2], poly17_shift
[2],
407 pokey_audout
u_audout3(start_timer
, clk_i
, dat_i
,
409 poly4_shift
[3], poly5_shift
[3], poly17_shift
[3],