1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-19 17:27:59 +00:00

Finally get Sound every Time

This commit is contained in:
Gehstock 2018-12-18 17:28:18 +01:00
parent 45fc572d2d
commit 403b2f3351
29 changed files with 724 additions and 1584 deletions

View File

@ -48,8 +48,6 @@ set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Centipede.sv
set_global_assignment -name VERILOG_FILE rtl/centipede.v
set_global_assignment -name VHDL_FILE rtl/asteroids_pokey.vhd
set_global_assignment -name VERILOG_FILE rtl/pokey_atosm.v
set_global_assignment -name VERILOG_FILE rtl/pf_ram.v
set_global_assignment -name VERILOG_FILE rtl/p6502.v
set_global_assignment -name VERILOG_FILE rtl/bc6502.v
@ -164,4 +162,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# end ENTITY(Centipede)
# ---------------------
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Pokey/POKEY.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Pokey/matoro.sv
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -14,4 +14,4 @@
-- SPACE : Fire
-- ARROW KEYS : Movements
---------------------------------------------------------------------------------
Todo: Sound and Joystick
Todo: Joystick(Fire)

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

View File

@ -42,8 +42,7 @@ module Centipede
localparam CONF_STR = {
"Centipede;;",
"O1,Test,off,on;",
"O2,Cocktail,off,on;",
"O1,Test,off,on;",
"O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
"O5,Joystick Control,Upright,Normal;",
"T7,Reset;",
@ -62,7 +61,7 @@ wire ps2_kbd_clk, ps2_kbd_data;
assign LED = 1;
wire clk_24, clk_12, clk_6;
wire clk_24, clk_12, clk_6, clk_100mhz;
wire pll_locked;
pll pll
@ -71,30 +70,27 @@ pll pll
.areset(0),
.c0(clk_24),
.c2(clk_12),
.c3(clk_6)
.c3(clk_6),
.c4(clk_100mhz)
);
//ToDo Joystick breaks Controls
//wire m_up = status[5] ? ~kbjoy[6] | ~joystick_0[1] | ~joystick_1[1] : ~kbjoy[4] | ~joystick_0[3] | ~joystick_1[3];
//wire m_down = status[5] ? ~kbjoy[7] | ~joystick_0[0] | ~joystick_1[0] : ~kbjoy[5] | ~joystick_0[2] | ~joystick_1[2];
//wire m_left = status[5] ? ~kbjoy[5] | ~joystick_0[2] | ~joystick_1[2] : ~kbjoy[6] | ~joystick_0[1] | ~joystick_1[1];
//wire m_right = status[5] ? ~kbjoy[4] | ~joystick_0[3] | ~joystick_1[3] : ~kbjoy[7] | ~joystick_0[0] | ~joystick_1[0];
wire m_up = status[5] ? ~kbjoy[7] : ~kbjoy[4];
wire m_down = status[5] ? ~kbjoy[6] : ~kbjoy[5];
wire m_left = status[5] ? ~kbjoy[4] : ~kbjoy[6];
wire m_right = status[5] ? ~kbjoy[5] : ~kbjoy[7];
wire m_up = status[5] ? ~kbjoy[6] & ~joystick_0[1] & ~joystick_1[1] : ~kbjoy[4] & ~joystick_0[3] & ~joystick_1[3];
wire m_down = status[5] ? ~kbjoy[7] & ~joystick_0[0] & ~joystick_1[0] : ~kbjoy[5] & ~joystick_0[2] & ~joystick_1[2];
wire m_left = status[5] ? ~kbjoy[5] & ~joystick_0[2] & ~joystick_1[2] : ~kbjoy[6] & ~joystick_0[1] & ~joystick_1[1];
wire m_right = status[5] ? ~kbjoy[4] & ~joystick_0[3] & ~joystick_1[3] : ~kbjoy[7] & ~joystick_0[0] & ~joystick_1[0];
wire m_fire = ~kbjoy[0];// | ~joystick_0[4] | ~joystick_1[4] | ~joystick_0[5] | ~joystick_1[5];
wire m_start1 = ~kbjoy[1];
wire m_start2 = ~kbjoy[1];//ok
wire m_coin = ~kbjoy[3];
wire m_fire = ~kbjoy[0] | joystick_0[4] | joystick_1[4] | joystick_0[5] | joystick_1[5];
wire m_start = ~kbjoy[1];
wire m_coin = kbjoy[3];
wire m_test = ~status[1];
wire m_slam = 1'b1;
wire m_cocktail = 1'b1;
wire [9:0] playerinput_i = { m_coin, m_coin, m_coin, m_test, m_cocktail, m_slam, m_start1, m_start2, m_fire, m_fire };
wire [9:0] playerinput_i = { m_coin, m_coin, m_coin, m_test, m_cocktail, m_slam, m_start, m_start, m_fire, m_fire };
centipede centipede(
.clk_100mhz(clk_100mhz),
.clk_12mhz(clk_12),
.reset(status[0] | status[7] | buttons[1]),
.playerinput_i(playerinput_i),
@ -111,12 +107,12 @@ centipede centipede(
);
wire [7:0] audio;
wire [3:0] audio;
dac dac (
.clk_i(clk_24),
.res_n_i(1),
.dac_i(audio),
.dac_i({audio,audio,audio,audio}),
.dac_o(AUDIO_L)
);

View File

@ -0,0 +1,505 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: M-x Butterfly
// Engineer: Peter Pearson
//
// Create Date: 10/29/2015 03:59:30 PM
// Design Name:
// Module Name: POKEY
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module POKEY
(
input logic [7:0] Din,
output logic [7:0] Dout,
input logic [3:0] A,
input logic [7:0] P,
input logic phi2,
input logic readHighWriteLow,
input logic cs0Bar,
output logic aud,
output logic [3:0] audio,
//This clk is the 100 MHz clock, and is not a pin on the POKEY DIP
input logic clk
);
logic [7:0] audf1, audf2, audf3, audf4, audc1, audc2, audc3, audc4, audCtl, allPot, skCtl;
logic [7:0] dataIn, dataOut;
logic clr;
logic baseClkWave;
logic wave15k, pulse15k, wave64k, pulse64k, wave179m, pulse179m;
logic rand4, rand5, rand17, reduce9;
logic [7:0] rngRead;
logic phi2Rising;
logic [3:0] bypassMask1, bypassMask2, bypassMask3, bypassMask4;
//Outputs of the divide-by-N blocks for each channel
logic [3:0] divOut;
//Base clock fed to each channel
logic [3:0] baseClks;
//High pass filter clocks fed to each channel
logic [3:0] hpfClks;
//Output waveform of each channel
logic [3:0] rawWave;
assign clr = (skCtl[1:0] == 2'b00);
// tristateDriver #(8) triDrv(.i(dataOut), .o(D), .en(readHighWriteLow));
assign dataIn = Din;
assign Dout = dataOut;
wave15kGen w15k(.clk(clk), .clr(clr), .wave(wave15k), .pulse(pulse15k));
wave64kGen w64k(.clk(clk), .clr(clr), .wave(wave64k), .pulse(pulse64k));
wave179mGen w179m(.clk(clk), .clr(clr), .wave(wave179m), .pulse(pulse179m));
polyCounter4 pc4(.clk(clk), .pulse179m(pulse179m), .rand4(rand4), .clr(clr));
polyCounter5 pc5(.clk(clk), .pulse179m(pulse179m), .rand5(rand5), .clr(clr));
polyCounter17 pc17(.clk(clk), .pulse179m(pulse179m), .reduce9(reduce9), .rand17(rand17), .rngVal(rngRead), .clr(clr));
risingDetector risingPhi(.clk(clk), .clr(clr), .signalIn(phi2), .risingEdge(phi2Rising));
audioChannelDigital channel1(.clk(clk), .clr(clr), .baseClkWave(baseClks[0]), .audf(audf1), .audc(audc1), .rand4(rand4), .rand5(rand5), .rand17(rand17), .hpfClk(hpfClks[0]), .bypassMask(bypassMask1), .rawWave(rawWave[0]), .divOut(divOut[0]));
audioChannelDigital channel2(.clk(clk), .clr(clr), .baseClkWave(baseClks[1]), .audf(audf2), .audc(audc2), .rand4(rand4), .rand5(rand5), .rand17(rand17), .hpfClk(hpfClks[1]), .bypassMask(bypassMask2), .rawWave(rawWave[1]), .divOut(divOut[1]));
audioChannelDigital channel3(.clk(clk), .clr(clr), .baseClkWave(baseClks[2]), .audf(audf3), .audc(audc3), .rand4(rand4), .rand5(rand5), .rand17(rand17), .hpfClk(hpfClks[2]), .bypassMask(bypassMask3), .rawWave(rawWave[2]), .divOut(divOut[2]));
audioChannelDigital channel4(.clk(clk), .clr(clr), .baseClkWave(baseClks[3]), .audf(audf4), .audc(audc4), .rand4(rand4), .rand5(rand5), .rand17(rand17), .hpfClk(hpfClks[3]), .bypassMask(bypassMask4), .rawWave(rawWave[3]), .divOut(divOut[3]));
assign audio = {aud,aud,aud,aud};
volumeMixer finalMix(.clk(clk), .clr(clr), .audc1(audc1), .audc2(audc2), .audc3(audc3), .audc4(audc4), .digitalWave(rawWave), .pwmWave(aud));
assign hpfClks = {{divOut[2]},{divOut[3]},{2'b00}};
//AUDCTL and bypass mask logic
always_comb
begin
reduce9 = audCtl[7];
baseClks[0] = (audCtl[6] ? wave179m : baseClkWave);
baseClks[2] = (audCtl[5] ? wave179m : baseClkWave);
baseClks[1] = (audCtl[4] ? divOut[0] : baseClkWave);
baseClks[3] = (audCtl[3] ? divOut[2] : baseClkWave);
bypassMask1 = {{audCtl[2]},{3'b000}};
bypassMask2 = {{audCtl[1]},{3'b000}};
bypassMask3 = 4'h8;
bypassMask4 = 4'h8;
baseClkWave = (audCtl[0] ? wave15k : wave64k);
end
always_ff@(posedge clk)
begin
if(phi2Rising & !cs0Bar)
begin
if(clr)
begin
audf1 <= 8'd0;
audf2 <= 8'd0;
audf3 <= 8'd0;
audf4 <= 8'd0;
audc1 <= 8'd0;
audc2 <= 8'd0;
audc3 <= 8'd0;
audc4 <= 8'd0;
audCtl <= 8'd0;
allPot <= 8'd0;
dataOut <= 8'd0;
if(!readHighWriteLow & (A == 4'hF))
begin
skCtl <= dataIn;
end
end
else
begin
if(readHighWriteLow)
begin
case(A)
4'h8: dataOut <= allPot;
4'hA: dataOut <= rngRead;
endcase
end
else
begin
case(A)
4'h0: audf1 <= dataIn;
4'h1: audc1 <= dataIn;
4'h2: audf2 <= dataIn;
4'h3: audc2 <= dataIn;
4'h4: audf3 <= dataIn;
4'h5: audc3 <= dataIn;
4'h6: audf4 <= dataIn;
4'h7: audc4 <= dataIn;
4'h8: audCtl <= dataIn;
4'hB: allPot <= P;
4'hF: skCtl <= dataIn;
endcase // case (A)
end // else: !if(readHighWriteLow)
end
end
end
endmodule: POKEY
module tristateDriver
#(parameter WIDTH = 8)
(
input logic [WIDTH-1:0] i,
output logic [WIDTH-1:0] o,
input logic en
);
assign o = (en) ? i : ({WIDTH{1'bz}});
endmodule: tristateDriver
module volumeMixer
(
input logic clk, clr,
input logic [7:0] audc1, audc2, audc3, audc4,
input logic [3:0] digitalWave,
output logic pwmWave
);
logic [5:0] volume;
logic [5:0] pwmCnt;
assign volume =
((digitalWave[3] | audc4[4]) ? audc4[3:0] : 0) +
((digitalWave[2] | audc3[4]) ? audc3[3:0] : 0) +
((digitalWave[1] | audc2[4]) ? audc2[3:0] : 0) +
((digitalWave[0] | audc1[4]) ? audc1[3:0] : 0);
m_counter #(6) pwmClk(.Q(pwmCnt), .D(6'd0), .clk(clk), .clr(clr), .load(1'b0), .en(1'b1), .up(1'b1));
assign pwmWave = (pwmCnt < volume);
endmodule: volumeMixer
module audioChannelDigital
(
input logic clk, clr,
input logic baseClkWave,
input logic [7:0] audf, audc,
input logic rand4, rand5, rand17,
input logic hpfClk,
input logic [3:0] bypassMask,
output logic rawWave, divOut, noiseOut, arbDiv2Out
);
logic noise;
logic [3:0] sigIn, sigOut;
divideByN stage1(.signalIn(sigIn[0]), .clk(clk), .clr(clr), .N(audf), .signalOut(sigOut[0]));
noiseGen rng(.rand4(rand4), .rand5(rand5), .rand17(rand17), .noise(noise), .randSel(audc[7:5]));
randomMixer randMix(.clk(clk), .clr(clr), .randomIn(noise), .signalIn(sigIn[1]), .signalOut(sigOut[1]));
arbDivBy2 adb2(.clk(clk), .clr(clr), .signalIn(sigIn[2]), .signalOut(sigOut[2]));
highPassFilter hpf(.hpfClk(hpfClk), .clk(clk), .clr(clr), .inputSignal(sigIn[3]), .outputSignal(sigOut[3]));
assign sigIn[0] = baseClkWave;
assign sigIn[1] = bypassMask[0] ? sigIn[0] : sigOut[0];
assign sigIn[2] = bypassMask[1] ? sigIn[1] : sigOut[1];
assign sigIn[3] = bypassMask[2] ? sigIn[2] : sigOut[2];
assign rawWave = bypassMask[3] ? sigIn[3] : sigOut[3];
assign divOut = sigOut[0];
assign noiseOut = sigOut[1];
assign arbDiv2Out = sigOut[2];
endmodule: audioChannelDigital
module highPassFilter
(
input logic clk, clr,
input logic hpfClk,
input logic inputSignal,
output logic outputSignal
);
logic ffOut;
m_register #(1) filterReg(.Q(ffOut), .D(inputSignal), .clr(clr), .clk(clk), .en(hpfClk));
assign outputSignal = (inputSignal ^ ffOut);
endmodule: highPassFilter
module noiseGen
(
input logic rand4, rand5, rand17,
input logic [2:0] randSel,
output logic noise
);
always_comb
begin
casex(randSel)
3'b000:
begin
noise = rand5 & rand17;
end
3'b0?1:
begin
noise = rand5;
end
3'b010:
begin
noise = rand4 & rand5;
end
3'b100:
begin
noise = rand17;
end
3'b1?1:
begin
noise = 1'b1;
end
3'b110:
begin
noise = rand4;
end
default:
begin
noise = 1'b1;
end
endcase // casex (randSel)
end
endmodule: noiseGen
module edgeDetector
(
input logic clk, clr,
input logic signal,
output logic edgeFound
);
logic prevSignal;
m_register #(1) edgeRegister(.Q(prevSignal), .D(signal), .clk(clk), .clr(clr), .en(1'b1));
assign edgeFound = signal ^ prevSignal;
endmodule: edgeDetector
module divideByN
(
input logic signalIn, clk, clr,
input logic [7:0] N,
output logic signalOut
);
logic [7:0] countOut;
logic rollover, edgeFound;
edgeDetector edgeChecker(.clk(clk), .clr(clr), .signal(signalIn), .edgeFound(edgeFound));
m_counter #(8) divCounter(.D(8'd0), .Q(countOut), .clk(clk), .en(edgeFound), .up(1'b1), .clr(clr), .load(rollover));
m_register #(1) waveTracker(.Q(signalOut), .D(!signalOut), .clk(clk), .en(rollover), .clr(clr));
assign rollover = (countOut >= N) & edgeFound;
endmodule: divideByN
module wave15kGen
(
input logic clk, clr,
output logic wave, pulse
);
logic [11:0] parallel15k;
m_counter #(12) counter15k(.D(12'd0), .Q(parallel15k), .clk(clk), .en(1'b1), .up(1'b1), .clr(clr), .load(pulse));
m_register #(1) waveTracker(.D(!wave), .Q(wave), .clk(clk), .en(pulse), .clr(clr));
assign pulse = (parallel15k == 12'd3333);
endmodule: wave15kGen
module wave64kGen
(
input logic clk, clr,
output logic wave, pulse
);
logic [9:0] parallel64k;
m_counter #(10) counter64k(.D(10'd0), .Q(parallel64k), .clk(clk), .en(1'b1), .up(1'b1), .clr(clr), .load(pulse));
m_register #(1) waveTracker(.D(!wave), .Q(wave), .clk(clk), .en(pulse), .clr(clr));
assign pulse = (parallel64k == 10'd781);
endmodule: wave64kGen
module wave179mGen
(
input logic clk, clr,
output logic wave, pulse
);
logic [4:0] parallel179m;
m_counter #(5) counter64k(.D(5'd0), .Q(parallel179m), .clk(clk), .en(1'b1), .up(1'b1), .clr(clr), .load(pulse));
m_register #(1) waveTracker(.D(!wave), .Q(wave), .clk(clk), .en(pulse), .clr(clr));
assign pulse = (parallel179m == 5'd28);
endmodule: wave179mGen
module polyCounter4
(
input logic clk, pulse179m, clr,
output logic rand4
);
logic [3:0] regValue;
logic feedbackVal;
m_shift_register #(4) polyShifter(.Q(regValue), .clk(clk), .en(pulse179m), .left(1'b0), .s_in(feedbackVal), .clr(clr));
assign feedbackVal = !(regValue[3] ^ regValue[2]);
assign rand4 = regValue[3];
endmodule: polyCounter4
module polyCounter5
(
input logic clk, pulse179m, clr,
output logic rand5
);
logic [4:0] regValue;
logic feedbackVal;
m_shift_register #(5) polyShifter(.Q(regValue), .clk(clk), .en(pulse179m), .left(1'b1), .s_in(feedbackVal), .clr(clr));
assign feedbackVal = !(regValue[4] ^ regValue[2]);
assign rand5 = regValue[4];
endmodule: polyCounter5
module polyCounter17
(
input logic clk, pulse179m, clr,
input logic reduce9,
output logic rand17,
output logic [7:0] rngVal
);
logic [16:0] regValue;
logic feedbackVal;
m_shift_register #(9) polyShifterUpper(.Q(regValue[16:8]), .clk(clk), .en(pulse179m), .left(1'b1), .s_in(reduce9 ? feedbackVal : regValue[7]), .clr(clr));
m_shift_register #(8) polyShifterLower(.Q(regValue[7:0]), .clk(clk), .en(pulse179m), .left(1'b1), .s_in(feedbackVal), .clr(clr));
assign feedbackVal = !(regValue[16] ^ regValue[11]);
assign rand17 = regValue[16];
assign rngVal = regValue[16:9];
endmodule: polyCounter17
module volumeControl
(
input logic clk, clr,
input logic signalIn,
input logic [3:0] volume,
input logic dcVolume,
output logic signalOut
);
logic [3:0] pwmCount;
logic pwmOn;
m_counter #(4) pwmTimer(.Q(pwmCount), .D(4'h0), .clk(clk), .clr(clr), .load(1'b0), .en(1'b1), .up(1'b1));
assign pwmOn = (pwmCount <= volume);
assign signalOut = dcVolume ? pwmOn : (pwmOn & signalIn);
endmodule: volumeControl
module risingDetector
(
input logic clk, clr,
input logic signalIn,
output logic risingEdge
);
logic prevSignal;
m_register #(1) risingRegister(.Q(prevSignal), .D(signalIn), .en(1'b1), .clk(clk), .clr(clr));
assign risingEdge = signalIn & ~prevSignal;
endmodule: risingDetector
module randomMixer
(
input logic clk, clr,
input logic signalIn,
input logic randomIn,
output logic signalOut
);
logic risingEdge;
logic waveWideRandom;
//This instance name made sense at 4AM when I typed it
risingDetector rayfall(.clk(clk), .clr(clr), .signalIn(signalIn), .risingEdge(risingEdge));
m_register #(1) randomCapture(.Q(waveWideRandom), .D(randomIn), .en(risingEdge), .clk(clk), .clr(clr));
assign signalOut = signalIn & waveWideRandom;
endmodule: randomMixer
module arbDivBy2
(
input logic clk, clr,
input logic signalIn,
output logic signalOut
);
logic risingEdge;
risingDetector risingCheck(.clk(clk), .clr(clr), .signalIn(signalIn), .risingEdge(risingEdge));
m_register #(1) waveTracker(.Q(signalOut), .D(~signalOut), .en(risingEdge), .clk(clk), .clr(clr));
endmodule: arbDivBy2

View File

@ -0,0 +1,129 @@
`timescale 1ns / 1ps
module m_range_check
#(parameter WIDTH = 6)
(input logic [WIDTH-1:0] val, low, high,
output logic is_between);
logic smallEnough, largeEnough;
m_comparator #(WIDTH) lc(,,largeEnough, low, val);
m_comparator #(WIDTH) hc(,,smallEnough, val, high);
assign is_between = ~smallEnough & ~largeEnough;
endmodule: m_range_check
module m_offset_check
#(parameter WIDTH = 6)
(input logic [WIDTH-1:0] val, low, delta,
output logic is_between);
logic [WIDTH-1:0] high;
m_adder #(WIDTH) add(high,, low, delta, 1'b0);
m_range_check #(WIDTH) rc(.*);
endmodule: m_offset_check
module m_comparator
#(parameter WIDTH = 6)
(output logic AltB, AeqB, AgtB,
input logic [WIDTH-1:0] A, B);
assign AltB = (A < B);
assign AeqB = (A == B);
assign AgtB = (A > B);
endmodule: m_comparator
module m_adder
#(parameter WIDTH = 6)
(output logic [WIDTH-1:0] Sum,
output logic Cout,
input logic [WIDTH-1:0] A, B,
input logic Cin);
assign {Cout, Sum} = A + B + Cin;
endmodule: m_adder
module m_mux
#(parameter WIDTH = 6)
(output logic Y,
input logic [WIDTH-1:0] I,
input logic [$clog2(WIDTH)-1:0] Sel);
assign Y = I[Sel];
endmodule: m_mux
module m_mux2to1
#(parameter WIDTH = 6)
(output logic [WIDTH-1:0] Y,
input logic [WIDTH-1:0] I0, I1,
input logic Sel);
assign Y = (Sel ? I1 : I0);
endmodule: m_mux2to1
module m_decoder
#(parameter WIDTH = 6)
(output logic [(1 << WIDTH)-1:0] D,
input logic [WIDTH-1:0] I,
input logic en);
assign D = en << I;
endmodule: m_decoder
module m_register
#(parameter WIDTH = 6)
(output logic [WIDTH-1:0] Q,
input logic [WIDTH-1:0] D,
input logic clr, en, clk);
always_ff @(posedge clk)
if(clr)
Q <= 0;
else if(en)
Q <= D;
endmodule: m_register
module m_counter
#(parameter WIDTH = 6)
(output logic [WIDTH-1:0] Q,
input logic [WIDTH-1:0] D,
input logic clk, clr, load, en, up);
always_ff @(posedge clk) begin
if(clr)
Q <= 0;
else if(load)
Q <= D;
else if(en)
Q <= (up ? Q + 1 : Q - 1);
end
endmodule: m_counter
module m_shift_register
#(parameter WIDTH = 6)
(output logic [WIDTH-1:0] Q,
input logic clk, en, left, s_in, clr);
always_ff @(posedge clk)
if (clr) begin
Q <= 'd0;
end
else if(en) begin
if(left) begin
Q <= (Q << 1);
Q[0] <= s_in;
end
else begin
Q <= (Q >> 1);
Q[WIDTH-1] <= s_in;
end
end
endmodule: m_shift_register

View File

@ -1,562 +0,0 @@
--
-- A simulation model of Asteroids Deluxe hardware
-- Copyright (c) MikeJ - May 2004
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- You are responsible for any legal issues arising from your use of this code.
--
-- The latest version of this file can be found at: www.fpgaarcade.com
--
-- Email support@fpgaarcade.com
--
-- Revision list
--
-- version 002 return 00 on allpot when fast scan completed to fix self test
-- version 001 initial release (this version should be considered Beta
-- it seems to make all the right sort of sounds however ... )
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--use work.pkg_asteroids.all;
entity ASTEROIDS_POKEY is
port (
ADDR : in std_logic_vector(3 downto 0);
DIN : in std_logic_vector(7 downto 0);
DOUT : out std_logic_vector(7 downto 0);
DOUT_OE_L : out std_logic;
RW_L : in std_logic;
CS : in std_logic; -- used as enable
CS_L : in std_logic;
--
AUDIO_OUT : out std_logic_vector(7 downto 0);
--
PIN : in std_logic_vector(7 downto 0);
ENA : in std_logic;
CLK : in std_logic -- note 6 Mhz
);
end;
architecture RTL of ASTEROIDS_POKEY is
type array_8x8 is array (0 to 7) of std_logic_vector(7 downto 0);
type array_4x8 is array (1 to 4) of std_logic_vector(7 downto 0);
type array_4x4 is array (1 to 4) of std_logic_vector(3 downto 0);
type array_4x9 is array (1 to 4) of std_logic_vector(8 downto 0);
type array_2x17 is array (1 to 2) of std_logic_vector(16 downto 0);
type bool_4 is array (1 to 4) of boolean;
signal we : std_logic;
signal oe : std_logic;
--
signal ena_64k_15k : std_logic;
signal cnt_64k : std_logic_vector(4 downto 0) := (others => '0');
signal ena_64k : std_logic;
signal cnt_15k : std_logic_vector(6 downto 0) := (others => '0');
signal ena_15k : std_logic;
--
signal poly4 : std_logic_vector(3 downto 0) := (others => '0');
signal poly5 : std_logic_vector(4 downto 0) := (others => '0');
signal poly9 : std_logic_vector(8 downto 0) := (others => '0');
signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
signal poly_17_9 : std_logic;
-- registers
signal audf : array_4x8 := (x"00",x"00",x"00",x"00");
signal audc : array_4x8 := (x"00",x"00",x"00",x"00");
signal audctl : std_logic_vector(7 downto 0) := "00000000";
signal stimer : std_logic_vector(7 downto 0);
signal skres : std_logic_vector(7 downto 0);
signal potgo : std_logic;
signal serout : std_logic_vector(7 downto 0);
signal irqen : std_logic_vector(7 downto 0);
signal skctls : std_logic_vector(7 downto 0);
signal reset : std_logic;
--
signal kbcode : std_logic_vector(7 downto 0);
signal random : std_logic_vector(7 downto 0);
signal serin : std_logic_vector(7 downto 0);
signal irqst : std_logic_vector(7 downto 0);
signal skstat : std_logic_vector(7 downto 0);
--
signal pot_fin : std_logic;
signal pot_cnt : std_logic_vector(7 downto 0);
signal pot_val : array_8x8;
signal pin_reg : std_logic_vector(7 downto 0);
signal pin_reg_gated : std_logic_vector(7 downto 0);
--
signal chan_ena : std_logic_vector(4 downto 1);
signal tone_gen_div : std_logic_vector(4 downto 1);
signal tone_gen_cnt : array_4x8 := (others => (others => '0'));
signal tone_gen_div_mux : std_logic_vector(4 downto 1);
signal tone_gen_zero : std_logic_vector(4 downto 1);
signal tone_gen_zero_t : array_4x8 := (others => (others => '0'));
signal chan_done_load : std_logic_vector(4 downto 1) := (others => '0');
--
signal poly_sel : std_logic_vector(4 downto 1);
signal poly_sel_hp : std_logic_vector(4 downto 1);
signal poly_sel_hp_t1 : std_logic_vector(4 downto 1);
signal poly_sel_hp_reg : std_logic_vector(4 downto 1);
signal tone_gen_final : std_logic_vector(4 downto 1) := (others => '0');
begin
p_we : process(RW_L, CS_L, CS, ENA)
begin
we <= (not CS_L) and CS and (not RW_L) and ENA;
end process;
p_oe : process(RW_L, CS_L, CS)
begin
oe <= (not CS_L) and CS and RW_L;
end process;
DOUT_OE_L <= not oe;
p_ipreg : process
begin
wait until rising_edge(CLK);
-- in asteroids, these are dip switches
pin_reg <= PIN;
end process;
p_dividers : process
begin
wait until rising_edge(CLK);
if (ENA = '1') then
ena_64k <= '0';
if cnt_64k = "00000" then
cnt_64k <= "11011"; -- 28 - 1
ena_64k <= '1';
else
cnt_64k <= cnt_64k - "1";
end if;
ena_15k <= '0';
if cnt_15k = "0000000" then
cnt_15k <= "1110001"; -- 114 - 1
ena_15k <= '1';
else
cnt_15k <= cnt_15k - "1";
end if;
end if;
end process;
p_ena_64k_15k : process(ena_64k, ena_15k, audctl)
begin
if (audctl(0) = '1') then
ena_64k_15k <= ena_15k;
else
ena_64k_15k <= ena_64k;
end if;
end process;
p_poly : process
variable poly9_zero : std_logic;
variable poly17_zero : std_logic;
begin
wait until rising_edge(CLK);
if (ENA = '1') then
poly4 <= poly4(2 downto 0) & not (poly4(3) xor poly4(2));
poly5 <= poly5(3 downto 0) & not (poly5(4) xor poly4(2)); -- used inverted
-- not correct
poly9_zero := '0';
if (poly9 = "000000000") then poly9_zero := '1'; end if;
poly9 <= poly9(7 downto 0) & (poly9(8) xor poly9(3) xor poly9_zero);
poly17_zero := '0';
if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
poly17 <= poly17(15 downto 0) & (poly17(16) xor poly17(2) xor poly17_zero);
end if;
end process;
p_random_mux : process(audctl, poly9, poly17)
begin
-- bit unnecessary this ....
for i in 0 to 7 loop
if (audctl(7) = '1') then -- 9 bit poly
random(i) <= poly9(8-i);
else
random(i) <= poly17(16-i);
end if;
end loop;
if (audctl(7) = '1') then
poly_17_9 <= poly9(8);
else
poly_17_9 <= poly17(16);
end if;
end process;
p_wdata : process
begin
wait until rising_edge(CLK);
potgo <= '0';
--if (reset = '1') then
-- no idea what the reset state is
--audf <= (others => (others => '0'));
--audc <= (others => (others => '0'));
--audctl <= x"00";
--else
if (we = '1') then
case ADDR is
when x"0" => audf(1) <= DIN;
when x"1" => audc(1) <= DIN;
when x"2" => audf(2) <= DIN;
when x"3" => audc(2) <= DIN;
when x"4" => audf(3) <= DIN;
when x"5" => audc(3) <= DIN;
when x"6" => audf(4) <= DIN;
when x"7" => audc(4) <= DIN;
when x"8" => audctl <= DIN;
when x"9" => stimer <= DIN;
when x"A" => skres <= DIN;
when x"B" => potgo <= '1';
--when x"C" =>
when x"D" => serout <= DIN;
when x"E" => irqen <= DIN;
when x"F" => skctls <= DIN;
when others => null;
end case;
end if;
--end if;
end process;
p_reset : process(skctls)
begin
-- chip in reset if bits 1..0 of skctls are both zero
reset <= '0';
if (skctls(1 downto 0) = "00") then
reset <= '1';
end if;
end process;
p_rdata : process(oe, ADDR, pot_val, pin_reg_gated, kbcode, random, serin, irqst, skstat)
begin
DOUT <= x"00";
if (oe = '1') then -- keep things quiet
case ADDR IS
when x"0" => DOUT <= pot_val(0); -- pot 0
when x"1" => DOUT <= pot_val(1); -- pot 1
when x"2" => DOUT <= pot_val(2); -- pot 2
when x"3" => DOUT <= pot_val(3); -- pot 3
when x"4" => DOUT <= pot_val(4); -- pot 4
when x"5" => DOUT <= pot_val(5); -- pot 5
when x"6" => DOUT <= pot_val(6); -- pot 6
when x"7" => DOUT <= pot_val(7); -- pot 7
when x"8" => DOUT <= pin_reg_gated;-- allpot
when x"9" => DOUT <= kbcode;
when x"A" => DOUT <= random;
when x"B" => DOUT <= x"FF";
when x"C" => DOUT <= x"FF";
when x"D" => DOUT <= serin;
when x"E" => DOUT <= irqst;
when x"F" => DOUT <= skstat;
when others => null;
end case;
end if;
end process;
-- POT ANALOGUE IN UNTESTED !!
p_pot_cnt : process
begin
wait until rising_edge(CLK);
if (potgo = '1') then
pot_cnt <= x"00";
elsif ((ena_15k = '1') or (skctls(2) = '1')) and (ENA = '1') then -- fast scan mode
pot_cnt <= pot_cnt + "1";
end if;
end process;
p_pot_comp : process
begin
wait until rising_edge(CLK);
if (reset = '1') then
pot_fin <= '1';
else
if (potgo = '1') then
pot_fin <= '0';
elsif (pot_cnt = x"E4") then -- 228
pot_fin <= '1';
end if;
end if;
end process;
p_pot_val : process
begin
wait until rising_edge(CLK);
for i in 0 to 7 loop
if (pot_fin = '0') and (pin_reg(i) = '0') then
-- continue latching counter value until input reaches ViH threshold
pot_val(i) <= pot_cnt;
end if;
end loop;
end process;
-- dump transistors
--PIN <= x"00" when (pot_fin = '1') else (others => 'Z');
p_in_gate : process(pin_reg, reset) -- dump transistor fakeup
begin
pin_reg_gated <= pin_reg;
-- I think the datasheet lies about dump transistors being disabled
-- in fast scan mode, as the self test fails ....
if (reset = '1') or (pot_fin = '1') then --and (skctls(2) = '0'))
pin_reg_gated <= x"00";
end if;
end process;
p_tone_cnt_ena : process(audctl, ena_64k_15k, tone_gen_div)
variable chan_ena1, chan_ena3 : std_ulogic;
begin
if (audctl(6) = '1') then
chan_ena1 := '1'; -- 1.5 MHz,
else
chan_ena1 := ena_64k_15k;
end if;
chan_ena(1) <= chan_ena1;
if (audctl(4) = '1') then -- chan 1/2 joined
chan_ena(2) <= chan_ena1;
else
chan_ena(2) <= ena_64k_15k;
end if;
if (audctl(5) = '1') then
chan_ena3 := '1'; -- 1.5 MHz,
else
chan_ena3 := ena_64k_15k; -- 64 KHz
end if;
chan_ena(3) <= chan_ena3;
if (audctl(3) = '1') then -- chan 3/4 joined
chan_ena(4) <= chan_ena3;
else
chan_ena(4) <= ena_64k_15k; -- 64 KHz
end if;
end process;
p_tone_generator_zero : process(tone_gen_cnt, chan_ena)
begin
for i in 1 to 4 loop
if (tone_gen_cnt(i) = "00000000") and (chan_ena(i) = '1') then
tone_gen_zero(i) <= '1';
else
tone_gen_zero(i) <= '0';
end if;
end loop;
end process;
p_tone_generators : process
variable chan_load : std_logic_vector(4 downto 1);
variable chan_dec : std_logic_vector(4 downto 1);
begin
-- quite tricky this .. but I think it does the correct stuff
-- bet this is not how is was done originally !
--
-- nasty frig to easily get exact chip behaviour in high speed mode
-- fout = fin / 2(audf + n) when n=4 or 7 in 16 bit mode
wait until rising_edge(CLK);
if (ENA = '1') then
tone_gen_div <= "0000";
if (audctl(4) = '1') then -- chan 1/2 joined
chan_load(1) := '0';
chan_load(2) := '0';
if (tone_gen_zero_t(1)(5) = '1') and (tone_gen_zero_t(2)(5) = '1') and (chan_done_load(1) = '0') then
chan_load(1) := '1';
chan_load(2) := '1';
end if;
chan_dec(1) := '1';
chan_dec(2) := tone_gen_zero(1);
else
chan_load(1) := tone_gen_zero_t(1)(2) and not chan_done_load(1);
chan_load(2) := tone_gen_zero_t(2)(2) and not chan_done_load(2);
chan_dec(1) := '1';
chan_dec(2) := '1';
end if;
if (audctl(3) = '1') then -- chan 1/2 joined
chan_load(3) := '0';
chan_load(4) := '0';
if (tone_gen_zero_t(3)(5) = '1') and (tone_gen_zero_t(4)(5) = '1') and (chan_done_load(3) = '0') then
chan_load(3) := '1';
chan_load(4) := '1';
end if;
chan_dec(3) := '1';
chan_dec(4) := tone_gen_zero(3);
else
chan_load(3) := tone_gen_zero_t(3)(2) and not chan_done_load(3);
chan_load(4) := tone_gen_zero_t(4)(2) and not chan_done_load(4);
chan_dec(3) := '1';
chan_dec(4) := '1';
end if;
for i in 1 to 4 loop
if (chan_load(i) = '1') then
chan_done_load(i) <= '1';
tone_gen_div(i) <= '1';
tone_gen_cnt(i) <= audf(i);
elsif (chan_dec(i) = '1') and (chan_ena(i) = '1') then
chan_done_load(i) <= '0';
tone_gen_cnt(i) <= tone_gen_cnt(i) - "1";
end if;
tone_gen_div(i) <= chan_load(i);
tone_gen_zero_t(i)(7 downto 0) <= tone_gen_zero_t(i)(6 downto 0) & tone_gen_zero(i);
end loop;
end if;
end process;
p_tone_generator_mux : process(audctl, tone_gen_div)
begin
if (audctl(4) = '1') then -- chan 1/2 joined
tone_gen_div_mux(1) <= tone_gen_div(1); -- do they both waggle
tone_gen_div_mux(2) <= tone_gen_div(2); -- or do I mute chan 1?
else
tone_gen_div_mux(1) <= tone_gen_div(1);
tone_gen_div_mux(2) <= tone_gen_div(2);
end if;
if (audctl(3) = '1') then -- chan 3/4 joined
tone_gen_div_mux(3) <= tone_gen_div(3); -- ditto
tone_gen_div_mux(4) <= tone_gen_div(4);
else
tone_gen_div_mux(3) <= tone_gen_div(3);
tone_gen_div_mux(4) <= tone_gen_div(4);
end if;
end process;
p_poly_gating : process(audc, poly4, poly5, poly_17_9, tone_gen_div_mux)
variable filter_a : std_logic_vector(4 downto 1);
variable filter_b : std_logic_vector(4 downto 1);
begin
for i in 1 to 4 loop
if (audc(i)(7) = '0') then
filter_a(i) := poly5(4) and tone_gen_div_mux(i);-- 5 bit poly
else
filter_a(i) := tone_gen_div_mux(i);
end if;
if (audc(i)(6) = '0') then
filter_b(i) := poly_17_9 and filter_a(i);-- 17 bit poly
else
filter_b(i) := poly4(3) and filter_a(i);-- 4 bit poly
end if;
if (audc(i)(5) = '0') then
poly_sel(i) <= filter_b(i);
else
poly_sel(i) <= filter_a(i);
end if;
end loop;
end process;
p_high_pass_filters : process(audctl, poly_sel, poly_sel_hp_reg)
begin
poly_sel_hp <= poly_sel;
if (audctl(2) = '1') then
poly_sel_hp(1) <= poly_sel(1) xor poly_sel_hp_reg(1);
end if;
if (audctl(1) = '1') then
poly_sel_hp(2) <= poly_sel(2) xor poly_sel_hp_reg(2);
end if;
end process;
p_audio_out : process
begin
wait until rising_edge(CLK);
if (ENA = '1') then
for i in 1 to 4 loop
-- filter reg
if (tone_gen_div(3) = '1') then -- tone gen 1 clocked by gen 3
poly_sel_hp_reg(1) <= poly_sel(1);
end if;
if (tone_gen_div(4) = '1') then -- tone gen 2 clocked by gen 4
poly_sel_hp_reg(2) <= poly_sel(2);
end if;
poly_sel_hp_t1 <= poly_sel_hp;
if (poly_sel_hp(i) = '1') and (poly_sel_hp_t1(i) = '0') then -- rising edge
tone_gen_final(i) <= not tone_gen_final(i);
end if;
end loop;
end if;
end process;
p_op_mixer : process
variable vol : array_4x4;
variable sum12 : std_logic_vector(4 downto 0);
variable sum34 : std_logic_vector(4 downto 0);
variable sum : std_logic_vector(5 downto 0);
begin
wait until rising_edge(CLK);
if (ENA = '1') then
for i in 1 to 4 loop
if (audc(i)(4) = '1') then -- vol only
vol(i) := audc(i)(3 downto 0);
else
if (tone_gen_final(i) = '1') then
vol(i) := audc(i)(3 downto 0);
else
vol(i) := "0000";
end if;
end if;
end loop;
sum12 := ('0' & vol(1)) + ('0' & vol(2));
sum34 := ('0' & vol(3)) + ('0' & vol(4));
sum := ('0' & sum12) + ('0' & sum34);
if (reset = '1') then
AUDIO_OUT <= "00000000";
else
if (sum(5) = '0') then
AUDIO_OUT <= sum(4 downto 0) & "000";
else -- clip
AUDIO_OUT <= "11111111";
end if;
end if;
end if;
end process;
-- keyboard / serial etc to do
end architecture RTL;

View File

@ -1,2 +1,2 @@
`define BUILD_DATE "181124"
`define BUILD_TIME "140415"
`define BUILD_DATE "181218"
`define BUILD_TIME "170839"

View File

@ -19,6 +19,7 @@
`define orig_phi0
module centipede(
input clk_100mhz,
input clk_12mhz,
input clk_1p5mhz,
input reset,
@ -34,7 +35,7 @@ module centipede(
output vsync_o,
output hblank_o,
output vblank_o,
output [7:0] audio_o
output [3:0] audio_o
);
//
@ -379,8 +380,8 @@ ram(
end
else
begin
if (mpu_reset_cntr != 8'hff)
// if (mpu_reset_cntr != 8'h10)
// if (mpu_reset_cntr != 8'hff)
if (mpu_reset_cntr != 8'h10)
mpu_reset_cntr <= mpu_reset_cntr + 8'd1;
else
mpu_reset <= 0;
@ -962,53 +963,19 @@ hs_ram(
// Audio output circuitry
pokey_atosm pokey(
.rst_i(mpu_reset),
.clk_i(phi2),
.adr_i(ab[3:0]),
.dat_i(db_out[7:0]),
.dat_o(pokey_out),
.we_i(~rw_n),
.stb_i(1'b1 & ~pokey_n),
.ack_o(),
.irq(),
.audout(audio),
.p_i(8'b0),
.key_code(8'b0),
.key_pressed(1'b0),
.key_shift(1'b0),
.key_break(1'b0),
.serout(),
.serout_rdy_o(),
.serout_ack_i(),
.serin(8'b0),
.serin_rdy_i(1'b0),
.serin_ack_o()
);
/*
ASTEROIDS_POKEY ASTEROIDS_POKEY (
.ADDR(ab[3:0]),
.DIN(db_out[7:0]),
.DOUT(pokey_out),
.DOUT_OE_L(),
.RW_L(rw_n),
.CS(~pokey_n),
.CS_L(1'b0),
.AUDIO_OUT(audio),
.PIN(8'b0),
.ENA(1'b1),//1.5m
.CLK(phi2)//6m
);*/
//
reg [7:0] last_pokey_rd;
always @(posedge s_6mhz)
if (reset)
last_pokey_rd <= 0;
else
if (~pokey_n)
last_pokey_rd <= pokey_out;
POKEY POKEY(
.Din(db_out[7:0]),
.Dout(pokey_out),
.A(ab[3:0]),
.P(8'b0),
.phi2(phi2),
.readHighWriteLow(rw_n),
.cs0Bar(pokey_n),
.audio(audio),
.clk(clk_100mhz)
);
// Video output circuitry
// The video output circuit receives motion object, playfield, address and data inputs

View File

@ -1,8 +1,4 @@
//`define no_cpu
`define bc_cpu
//`define sim_cpu
module p6502(
input clk,
input reset_n,
@ -18,333 +14,7 @@ module p6502(
output [7:0] dout
);
`ifdef no_cpu
// assign rw_n = 1'b1;
// assign a = 0;
// assign dout = 0;
reg cpu_rw_n;
reg [15:0] cpu_a;
reg [7:0] cpu_dout;
reg [7:0] data;
assign rw_n = cpu_rw_n;
assign a = cpu_a;
assign dout = cpu_dout;
assign phi2 = ~phi0;
task cpu_wr;
input [15:0] addr;
input [7:0] data;
begin
$display("cpu_wr %x <- %x", addr, data);
@(posedge phi0);
cpu_a = addr;
cpu_dout = data;
@(posedge phi0);
cpu_rw_n = 1'b0;
@(posedge phi0);
cpu_rw_n = 1'b1;
@(posedge phi0);
end
endtask
task cpu_rd;
input [15:0] addr;
output [7:0] data;
begin
$display("cpu_rd %x", addr);
@(posedge phi0);
cpu_a = addr;
cpu_dout = data;
@(posedge phi0);
cpu_rw_n = 1'b1;
@(posedge phi0);
cpu_rw_n = 1'b1;
@(posedge phi0);
end
endtask
task cpu_wr_pf;
input [7:0] a;
input [31:0] d;
reg [5:0] atop;
reg [7:0] b0, b1, b2, b3;
reg [15:0] a0, a1, a2, a3;
begin
b0 = d[7:0];
b1 = d[15:8];
b2 = d[23:16];
b3 = d[31:24];
atop = 6'b000001;
a0 = {atop, a[7:4], 2'd0, a[3:0]};
a1 = {atop, a[7:4], 2'd1, a[3:0]};
a2 = {atop, a[7:4], 2'd2, a[3:0]};
a3 = {atop, a[7:4], 2'd3, a[3:0]};
$display("a %x -> a0 %x %x %x %x", a, a0, a1, a2, a3);
cpu_wr(a0, b0);
cpu_wr(a1, b1);
cpu_wr(a2, b2);
cpu_wr(a3, b3);
end
endtask
`ifdef never
task cpu_wr_mapped;
input [12:0] cpu_a;
input [7:0] cpu_d;
reg [7:0] r_a;
reg [3:0] r_w;
begin
r_a = { cpu_a[9:6], cpu_a[3:0] };
case (cpu_a[5:4])
2'b00: r_w = 4'b1110;
2'b01: r_w = 4'b1101;
2'b10: r_w = 4'b1011;
2'b11: r_w = 4'b0111;
endcase
$display("%x %x -> %x %b", cpu_a, cpu_d, r_a, r_w);
if (~r_w[3])
ram3[r_a] = cpu_d;
else
if (~r_w[2])
ram2[r_a] = cpu_d;
else
if (~r_w[1])
ram1[r_a] = cpu_d;
else
if (~r_w[0])
ram0[r_a] = cpu_d;
end
endtask
`endif
integer i;
initial
begin
cpu_rw_n = 1'b1;
cpu_a = 0;
cpu_dout = 0;
`ifdef never
for (i = 'h400; i < 'h7c0; i = i + 1)
cpu_wr(i, 8'h00);
`endif
#1000;
$display("nocpu: init");
`ifdef never
cpu_wr(16'h07c0, 8'h01);
cpu_rd(16'h07c0, data);
cpu_wr(16'h07d0, 8'h02);
cpu_rd(16'h07d0, data);
cpu_wr(16'h07e0, 8'h03);
cpu_rd(16'h07e0, data);
cpu_wr(16'h0400, 8'haa);
cpu_rd(16'h0400, data);
cpu_wr(16'h0410, 8'hbb);
cpu_rd(16'h0410, data);
#20;
$finish;
`endif
`ifdef never
cpu_wr(16'h0400, 8'h00);
cpu_wr(16'h0401, 8'h01);
cpu_wr(16'h0402, 8'h02);
cpu_wr(16'h0403, 8'h03);
cpu_wr(16'h0400, 8'h00);
cpu_wr(16'h0410, 8'h11);
cpu_wr(16'h0420, 8'h22);
cpu_wr(16'h0430, 8'h33);
cpu_rd(16'h0400, data);
cpu_rd(16'h0401, data);
cpu_rd(16'h0402, data);
cpu_rd(16'h0403, data);
cpu_rd(16'h0400, data);
cpu_rd(16'h0410, data);
cpu_rd(16'h0420, data);
cpu_rd(16'h0430, data);
`endif
`ifdef never
cpu_wr_pf(8'd240, 32'h39f08606);
cpu_wr_pf(8'd241, 32'h3df27e0d);
cpu_wr_pf(8'd242, 32'h3df88384);
cpu_wr_pf(8'd243, 32'h3df88b83);
cpu_wr_pf(8'd244, 32'h3df89382);
cpu_wr_pf(8'd245, 32'h3df89b81);
cpu_wr_pf(8'd246, 32'h3df8a380);
cpu_wr_pf(8'd247, 32'h3df8ab87);
cpu_wr_pf(8'd248, 32'h3df8b386);
cpu_wr_pf(8'd249, 32'h3df8bb85);
cpu_wr_pf(8'd250, 32'h3df8c384);
cpu_wr_pf(8'd251, 32'h3df8cb83);
cpu_wr_pf(8'd252, 32'h39f8dc1c);
cpu_wr_pf(8'd253, 32'h7960fff8);
cpu_wr_pf(8'd254, 32'h39388211);
cpu_wr_pf(8'd255, 32'h390f8710);
`endif
cpu_wr_pf(8'hf0, 32'h39f08606);
cpu_wr_pf(8'hf1, 32'h3df27e0d);
cpu_wr_pf(8'hf2, 32'h39e88384);
cpu_wr_pf(8'hf3, 32'h39e88b83);
cpu_wr_pf(8'hf4, 32'h39e89382);
cpu_wr_pf(8'hf5, 32'h39e8a986);
cpu_wr_pf(8'hf6, 32'h39e8a380);
cpu_wr_pf(8'hf7, 32'h39e8ab87);
cpu_wr_pf(8'hf8, 32'h39e8b386);
cpu_wr_pf(8'hf9, 32'h39e8bb85);
cpu_wr_pf(8'hfa, 32'h39e8c384);
cpu_wr_pf(8'hfb, 32'h39e8cb83);
cpu_wr_pf(8'hfc, 32'h39e8dc1c);
cpu_wr_pf(8'hfd, 32'h7960fff8);
cpu_wr_pf(8'hfe, 32'h39388211);
cpu_wr_pf(8'hff, 32'h390f8710);
cpu_wr(16'h501, 8'h01);
cpu_wr(16'h521, 8'h14);
cpu_wr(16'h541, 8'h01);
cpu_wr(16'h561, 8'h12);
cpu_wr(16'h581, 8'h09);
cpu_wr(16'h502, 8'h14);
cpu_wr(16'h522, 8'h05);
cpu_wr(16'h542, 8'h13);
cpu_wr(16'h562, 8'h14);
cpu_wr(16'h582, 8'h00);
cpu_wr(16'h503, 8'h1b);
cpu_wr(16'h523, 8'h21);
cpu_wr(16'h543, 8'h29);
cpu_wr(16'h563, 8'h28);
cpu_wr(16'h583, 8'h20);
#10000;
#100000000;
$finish;
`ifdef never
cpu_wr(16'h07c5, 8'h11);
cpu_wr(16'h07d5, 8'hb7);
cpu_wr(16'h07e5, 8'hf0);
cpu_wr(16'h07f5, 8'h39);
cpu_wr(16'h07c4, 8'h11);
cpu_wr(16'h07d4, 8'h10);
cpu_wr(16'h07e4, 8'hf0);
cpu_wr(16'h07f4, 8'h39);
cpu_wr(16'h07c3, 8'h11);
cpu_wr(16'h07d3, 8'h40);
cpu_wr(16'h07e3, 8'h2c);
cpu_wr(16'h07f3, 8'h39);
cpu_wr(16'h07c2, 8'h10);
cpu_wr(16'h07d2, 8'h60);
cpu_wr(16'h07e2, 8'hf8);
cpu_wr(16'h07f2, 8'h3d);
cpu_wr(16'h07c1, 8'h12);
cpu_wr(16'h07d1, 8'h80);
cpu_wr(16'h07e1, 8'h02);
cpu_wr(16'h07f1, 8'h39);
`endif
`ifdef never
cpu_wr(16'h07ee, 8'h2c);
cpu_wr(16'h07de, 8'hb7);
cpu_wr(16'h07ce, 8'h11);
cpu_wr(16'h07fe, 8'h39);
cpu_wr(16'h07ed, 8'h60);
cpu_wr(16'h07dd, 8'hff);
cpu_wr(16'h07cd, 8'hf8);
cpu_wr(16'h07fd, 8'h79);
cpu_wr(16'h07ec, 8'hf8);
cpu_wr(16'h07dc, 8'h14);
cpu_wr(16'h07cc, 8'h1c);
cpu_wr(16'h07fc, 8'h39);
cpu_wr(16'h07eb, 8'hf0);
cpu_wr(16'h07db, 8'h8e);
cpu_wr(16'h07cb, 8'h03);
cpu_wr(16'h07fb, 8'h3d);
cpu_wr(16'h07ea, 8'hf0);
cpu_wr(16'h07da, 8'h96);
cpu_wr(16'h07ca, 8'h04);
cpu_wr(16'h07fa, 8'h3d);
cpu_wr(16'h07e9, 8'hf0);
cpu_wr(16'h07d9, 8'h9e);
cpu_wr(16'h07c9, 8'h05);
cpu_wr(16'h07f9, 8'h3d);
cpu_wr(16'h07e8, 8'hf0);
cpu_wr(16'h07d8, 8'ha6);
cpu_wr(16'h07c8, 8'h06);
cpu_wr(16'h07f8, 8'h3d);
cpu_wr(16'h07e7, 8'hf0);
cpu_wr(16'h07d7, 8'hae);
cpu_wr(16'h07c7, 8'h07);
cpu_wr(16'h07f7, 8'h3d);
cpu_wr(16'h07e6, 8'hf0);
cpu_wr(16'h07d6, 8'hb6);
cpu_wr(16'h07c6, 8'h00);
cpu_wr(16'h07f6, 8'h3d);
cpu_wr(16'h07e5, 8'hf0);
cpu_wr(16'h07d5, 8'hbe);
cpu_wr(16'h07c5, 8'h01);
cpu_wr(16'h07f5, 8'h3d);
cpu_wr(16'h07e4, 8'hf0);
cpu_wr(16'h07d4, 8'hc6);
cpu_wr(16'h07c4, 8'h02);
cpu_wr(16'h07f4, 8'h3d);
cpu_wr(16'h07e3, 8'hf0);
cpu_wr(16'h07d3, 8'hce);
cpu_wr(16'h07c3, 8'h03);
cpu_wr(16'h07f3, 8'h3d);
cpu_wr(16'h07e2, 8'hf0);
cpu_wr(16'h07d2, 8'hd6);
cpu_wr(16'h07c2, 8'h04);
cpu_wr(16'h07f2, 8'h3d);
cpu_wr(16'h07e1, 8'hf0);
cpu_wr(16'h07d1, 8'hde);
cpu_wr(16'h07c1, 8'h05);
cpu_wr(16'h07f1, 8'h3d);
cpu_wr(16'h07e0, 8'hf0);
cpu_wr(16'h07d0, 8'he6);
cpu_wr(16'h07c0, 8'h06);
cpu_wr(16'h07f0, 8'h39);
`endif
$display("nocpu: done");
end
`endif
`ifdef bc_cpu
wire [15:0] ma;
wire reset;
wire rw;
@ -364,60 +34,6 @@ module p6502(
// assign phi2 = clk;
assign phi2 = ~phi0;
`ifdef SIMULATION
//
integer pccount;
initial
pccount = 0;
always @(posedge clk)
begin
if (bc6502.s_sync)
begin
pccount = pccount + 1;
if (pccount == 1000/* || $time > 9999999*/)
begin
pccount = 0;
`ifdef debug_cpu
$display("%t; cpu: pc %x; a=%x x=%x", $time, bc6502.pc_reg, bc6502.a_reg, bc6502.x_reg);
`ifndef verilator
$fflush;
$flushlog;
`endif
`endif
end
if (^bc6502.pc_reg === 1'bX ||
^bc6502.a_reg === 1'bX ||
^bc6502.x_reg === 1'bX ||
^bc6502.y_reg === 1'bX)
begin
$display("%t; cpu: x's in pc, a, x or y", $time);
$finish;
end
if (^a === 1'bX || ^din === 1'bX || ^dout === 1'bX)
begin
$display("%t; cpu: x's in addr bus or data bus", $time);
$finish;
end
end
end
`endif // SIMULATION
`endif // bc_cpu
`ifdef sim_cpu
reg cpu_rw_n;
reg [15:0] cpu_a;
reg [7:0] cpu_dout;
reg [7:0] data;
assign rw_n = cpu_rw_n;
assign a = cpu_a;
assign dout = cpu_dout;
assign phi2 = ~phi0;
`endif
endmodule // p6502

View File

@ -14,7 +14,7 @@
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 13.1.0 Build 162 10/23/2013 SJ Web Edition
-- 13.0.1 Build 232 06/12/2013 SP 1 SJ Full Version
-- ************************************************************
@ -47,7 +47,8 @@ ENTITY pll IS
c0 : OUT STD_LOGIC ;
c1 : OUT STD_LOGIC ;
c2 : OUT STD_LOGIC ;
c3 : OUT STD_LOGIC
c3 : OUT STD_LOGIC ;
c4 : OUT STD_LOGIC
);
END pll;
@ -60,9 +61,10 @@ ARCHITECTURE SYN OF pll IS
SIGNAL sub_wire3 : STD_LOGIC ;
SIGNAL sub_wire4 : STD_LOGIC ;
SIGNAL sub_wire5 : STD_LOGIC ;
SIGNAL sub_wire6 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire7_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire7 : STD_LOGIC_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire6 : STD_LOGIC ;
SIGNAL sub_wire7 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire8_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire8 : STD_LOGIC_VECTOR (0 DOWNTO 0);
@ -85,6 +87,10 @@ ARCHITECTURE SYN OF pll IS
clk3_duty_cycle : NATURAL;
clk3_multiply_by : NATURAL;
clk3_phase_shift : STRING;
clk4_divide_by : NATURAL;
clk4_duty_cycle : NATURAL;
clk4_multiply_by : NATURAL;
clk4_phase_shift : STRING;
compensate_clock : STRING;
inclk0_input_frequency : NATURAL;
intended_device_family : STRING;
@ -143,8 +149,9 @@ ARCHITECTURE SYN OF pll IS
END COMPONENT;
BEGIN
sub_wire7_bv(0 DOWNTO 0) <= "0";
sub_wire7 <= To_stdlogicvector(sub_wire7_bv);
sub_wire8_bv(0 DOWNTO 0) <= "0";
sub_wire8 <= To_stdlogicvector(sub_wire8_bv);
sub_wire5 <= sub_wire0(4);
sub_wire4 <= sub_wire0(2);
sub_wire3 <= sub_wire0(0);
sub_wire2 <= sub_wire0(3);
@ -153,8 +160,9 @@ BEGIN
c3 <= sub_wire2;
c0 <= sub_wire3;
c2 <= sub_wire4;
sub_wire5 <= inclk0;
sub_wire6 <= sub_wire7(0 DOWNTO 0) & sub_wire5;
c4 <= sub_wire5;
sub_wire6 <= inclk0;
sub_wire7 <= sub_wire8(0 DOWNTO 0) & sub_wire6;
altpll_component : altpll
GENERIC MAP (
@ -175,6 +183,10 @@ BEGIN
clk3_duty_cycle => 50,
clk3_multiply_by => 2,
clk3_phase_shift => "0",
clk4_divide_by => 13,
clk4_duty_cycle => 50,
clk4_multiply_by => 48,
clk4_phase_shift => "0",
compensate_clock => "CLK0",
inclk0_input_frequency => 37037,
intended_device_family => "Cyclone III",
@ -211,7 +223,7 @@ BEGIN
port_clk1 => "PORT_USED",
port_clk2 => "PORT_USED",
port_clk3 => "PORT_USED",
port_clk4 => "PORT_UNUSED",
port_clk4 => "PORT_USED",
port_clk5 => "PORT_UNUSED",
port_clkena0 => "PORT_UNUSED",
port_clkena1 => "PORT_UNUSED",
@ -227,7 +239,7 @@ BEGIN
)
PORT MAP (
areset => areset,
inclk => sub_wire6,
inclk => sub_wire7,
clk => sub_wire0
);
@ -258,14 +270,17 @@ END SYN;
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "3"
-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "9"
-- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "9"
-- Retrieval info: PRIVATE: DIV_FACTOR4 NUMERIC "13"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE4 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "24.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "18.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "12.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "6.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE4 STRING "99.692307"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@ -289,39 +304,47 @@ END SYN;
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "ps"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT4 STRING "ps"
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0"
-- Retrieval info: PRIVATE: MIRROR_CLK4 STRING "0"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "8"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
-- Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "4"
-- Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "2"
-- Retrieval info: PRIVATE: MULT_FACTOR4 NUMERIC "48"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "24.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "18.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "12.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "6.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ4 STRING "99.70000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE4 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT3 STRING "MHz"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT4 STRING "MHz"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT4 STRING "0.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "deg"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT4 STRING "deg"
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
@ -347,6 +370,7 @@ END SYN;
-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK3 STRING "1"
-- Retrieval info: PRIVATE: STICKY_CLK4 STRING "1"
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
@ -354,10 +378,12 @@ END SYN;
-- Retrieval info: PRIVATE: USE_CLK1 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK2 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK3 STRING "1"
-- Retrieval info: PRIVATE: USE_CLK4 STRING "1"
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA3 STRING "0"
-- Retrieval info: PRIVATE: USE_CLKENA4 STRING "0"
-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
@ -378,6 +404,10 @@ END SYN;
-- Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "2"
-- Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK4_DIVIDE_BY NUMERIC "13"
-- Retrieval info: CONSTANT: CLK4_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK4_MULTIPLY_BY NUMERIC "48"
-- Retrieval info: CONSTANT: CLK4_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
@ -413,7 +443,7 @@ END SYN;
-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_USED"
-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
@ -433,6 +463,7 @@ END SYN;
-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
-- Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
-- Retrieval info: USED_PORT: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3"
-- Retrieval info: USED_PORT: c4 0 0 0 0 OUTPUT_CLK_EXT VCC "c4"
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
-- Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
@ -441,6 +472,7 @@ END SYN;
-- Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
-- Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
-- Retrieval info: CONNECT: c3 0 0 0 0 @clk 0 0 1 3
-- Retrieval info: CONNECT: c4 0 0 0 0 @clk 0 0 1 4
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE

View File

@ -1,553 +0,0 @@
// Atosm Chip
// Copyright (C) 2008 Tomasz Malesinski <tmal@mimuw.edu.pl>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
module pokey_counter(clk_i, dat_i,
freq_ld, start, cnt_en,
out, borrow);
input clk_i;
input [7:0] dat_i;
input freq_ld;
input start;
input cnt_en;
output [7:0] out;
output borrow;
reg [7:0] freq;
reg [7:0] out;
assign borrow = (out == 0);
always @ (posedge clk_i)
if (start)
out <= freq;
else if (cnt_en)
out <= out - 8'd1;
always @ (posedge clk_i)
if (freq_ld)
freq <= dat_i;
endmodule
module pokey_basefreq(rst, clk_i, base15, out);
input rst;
input clk_i;
input base15;
output out;
reg [5:0] div57;
reg [1:0] div4;
assign out = (div57 == 0) && (!base15 || div4 == 0);
always @ (posedge clk_i)
if (rst) begin
div57 <= 6'b0;
div4 <= 2'b0;
end else if (div57 == 56) begin
div57 <= 0;
div4 <= div4 + 2'd1;
end else
div57 <= div57 + 6'd1;
endmodule
module pokey_poly4(rst, clk_i, out);
input rst;
input clk_i;
output out;
reg [3:0] shift;
assign out = shift[3];
always @ (posedge clk_i)
if (rst)
shift <= {shift[2:0], 1'b0};
else
shift <= {shift[2:0], shift[3] ~^ shift[2]};
endmodule
module pokey_poly5(rst, clk_i, out);
input rst;
input clk_i;
output out;
reg [4:0] shift;
assign out = shift[4];
always @ (posedge clk_i)
if (rst)
shift <= {shift[3:0], 1'b0};
else
shift <= {shift[3:0], shift[4] ~^ shift[2]};
endmodule
module pokey_poly17(rst, clk_i, short, out, random);
input rst;
input clk_i;
input short;
output out;
output [7:0] random;
reg [16:0] shift;
wire new_bit;
reg last_short;
assign out = shift[16];
assign random = shift[16:9];
assign new_bit = shift[16] ~^ shift[11];
// last_short is used to reset the shortened shift register when
// switching from long to short.
always @ (posedge clk_i)
if (rst)
last_short <= 0;
else
last_short <= short;
always @ (posedge clk_i)
if (rst)
shift <= 0;
else
shift <= {shift[15:8],
(short ? new_bit : shift[7]) & ~rst & (last_short | ~short),
shift[6:0], new_bit};
endmodule
module pokey_audout(rst, clk_i, dat_i,
audc_we,
poly4, poly5, poly17,
in, filter_en, filter_in,
out);
input rst;
input clk_i;
input [7:0] dat_i;
input audc_we;
input poly4, poly5, poly17;
input in, filter_en, filter_in;
output [3:0] out;
reg [3:0] vol;
reg vol_only;
reg no_poly5;
reg poly4_sel;
reg no_poly17_4;
reg nf, filter_reg;
wire change;
wire ch_out;
assign out = (ch_out | vol_only) ? vol : 4'b0;
assign change = in & (no_poly5 | poly5);
assign ch_out = filter_en ? filter_reg ^ nf : nf;
always @ (posedge clk_i)
if (audc_we) begin
vol <= dat_i[3:0];
vol_only <= dat_i[4];
no_poly5 <= dat_i[7];
poly4_sel <= dat_i[6];
no_poly17_4 <= dat_i[5];
end
always @ (posedge clk_i)
if (rst)
nf <= 0;
else if (change)
if (no_poly17_4)
nf <= ~nf;
else if (poly4_sel)
nf <= poly4;
else
nf <= poly17;
always @ (posedge clk_i)
if (!filter_en || rst)
filter_reg <= 0;
else if (filter_in)
filter_reg <= nf;
endmodule
module pokey_atosm(rst_i,
clk_i,
adr_i,
dat_i,
dat_o,
we_i,
stb_i,
ack_o,
irq,
audout,
p_i,
key_code, key_pressed, key_shift, key_break,
serout, serout_rdy_o, serout_ack_i,
serin, serin_rdy_i, serin_ack_o);
input rst_i;
input clk_i;
input [3:0] adr_i;
input [7:0] dat_i;
input we_i;
input stb_i;
input [7:0] key_code;
input key_pressed, key_shift, key_break;
input serout_ack_i;
input [7:0] serin;
input serin_rdy_i;
input [7:0] p_i;
output [7:0] dat_o;
output ack_o;
output irq;
output [5:0] audout;
output [7:0] serout;
output serout_rdy_o, serin_ack_o;
wire rst_i, clk_i;
wire [3:0] adr_i;
wire [7:0] dat_i;
wire we_i;
wire stb_i;
wire [7:0] key_code;
wire key_pressed, key_shift, key_break;
reg last_key_pressed, last_key_break;
wire ack_o;
reg [7:0] dat_o;
wire [5:0] audout;
wire [7:0] serin;
wire serin_rdy_i;
reg last_serin_rdy_i;
reg serin_ack_o;
reg [7:0] serout;
reg serout_rdy_o;
wire serout_ack_i;
reg last_serout_ack_i;
wire rst;
wire start_timer;
reg irq;
parameter [2:0] IRQ_BREAK = 7;
parameter [2:0] IRQ_KEY = 6;
parameter [2:0] IRQ_SERIN = 5;
parameter [2:0] IRQ_SEROUT = 4;
parameter [2:0] IRQ_SERFIN = 3;
parameter [2:0] IRQ_TIMER4 = 2;
parameter [2:0] IRQ_TIMER2 = 1;
parameter [2:0] IRQ_TIMER1 = 1;
reg [7:0] irqen;
reg [7:0] irqst;
// SKCTL bits.
reg [1:0] rst_bits;
// AUDCTL bits.
reg poly9;
reg fast_ch0;
reg fast_ch2;
reg ch01;
reg ch23;
reg fi02;
reg fi13;
reg base15;
reg [3:0] audf_we;
reg [3:0] audc_we;
wire [3:0] start;
wire [3:0] cnt_en;
wire [31:0] ctr_out;
wire [3:0] borrow;
wire poly4, poly5, poly17;
reg [3:1] poly4_shift, poly5_shift, poly17_shift;
wire base;
wire [3:0] audout0, audout1, audout2, audout3;
integer i, irq_i;
wire [7:0] random;
assign audout = {1'b0, audout0} + {1'b0, audout1} + {1'b0, audout2} + {1'b0, audout3};
assign rst = (rst_bits == 2'b00) | rst_i;
assign ack_o = stb_i;
//
reg [7:0] pot_done = 0;
reg [7:0] pot_cntr[0:7];
reg [7:0] pot_count;
// POTGO
always @ (posedge clk_i)
if (we_i && stb_i && adr_i == 'hb)
begin
pot_cntr[0] <= 8'h00;
pot_cntr[1] <= 8'h00;
pot_cntr[2] <= 8'h00;
pot_cntr[3] <= 8'h00;
pot_cntr[4] <= 8'h00;
pot_cntr[5] <= 8'h00;
pot_cntr[6] <= 8'h00;
pot_cntr[7] <= 8'h00;
pot_done <= 8'h00;
pot_count <= 0;
end // if (we_i && stb_i && adr_i == 'hb)
else
begin
if (pot_count != 8'hff)
pot_count <= pot_count + 8'd1;
else
pot_done <= 8'hff;
pot_cntr[0] <= p_i[0] ? 8'hff : 8'h00;
pot_cntr[1] <= p_i[1] ? 8'hff : 8'h00;
pot_cntr[2] <= p_i[2] ? 8'hff : 8'h00;
pot_cntr[3] <= p_i[3] ? 8'hff : 8'h00;
pot_cntr[4] <= p_i[4] ? 8'hff : 8'h00;
pot_cntr[5] <= p_i[5] ? 8'hff : 8'h00;
pot_cntr[6] <= p_i[6] ? 8'hff : 8'h00;
pot_cntr[7] <= p_i[7] ? 8'hff : 8'h00;
end
`ifdef never
always @ (adr_i or key_code or random or serin or irqst or irqen or
key_shift or key_pressed)
if (adr_i == 'h9)
// KBCODE
dat_o = key_code;
else if (adr_i == 'ha)
// RANDOM
dat_o = random;
else if (adr_i == 'hd)
// SERIN
dat_o = serin;
else if (adr_i == 'he)
// IRQST
dat_o = ~(irqst & irqen);
else if (adr_i == 'hf)
// SKSTAT
dat_o = {1'b1, // no framing error
1'b1, // no keyboard overrun
1'b1, // no serial data input over-run
1'b1, // serial input pad
~key_shift,
~key_pressed,
1'b1, // serial input shift register busy
1'b1}; // not used
else
dat_o = 'hff;
`else // !`ifdef never
always @ (adr_i or key_code or random or serin or irqst or irqen or
key_shift or key_pressed or pot_done or
pot_cntr[0] or pot_cntr[1] or pot_cntr[2] or pot_cntr[3] or
pot_cntr[4] or pot_cntr[5] or pot_cntr[6] or pot_cntr[7])
case (adr_i)
4'h0, 4'h1, 4'h2, 4'h3, 4'h4, 4'h5, 4'h6, 4'h7:
dat_o = pot_cntr[adr_i[2:0]];
4'h8: // ALLPOT
dat_o = pot_done;
4'h9: // KBCODE
dat_o = key_code;
4'ha: // RANDOM
dat_o = random;
4'hd: // SERIN
dat_o = serin;
4'he: // IRQST
dat_o = ~(irqst & irqen);
4'hf: // SKSTAT
dat_o = {1'b1, // no framing error
1'b1, // no keyboard overrun
1'b1, // no serial data input over-run
1'b1, // serial input pad
~key_shift,
~key_pressed,
1'b1, // serial input shift register busy
1'b1}; // not used
default:
dat_o = 'hff;
endcase
`endif // !`ifdef never
always @ (adr_i) begin
for (i = 0; i < 4; i = i + 1)
audf_we[i] = {28'b0, adr_i} == (i << 1);
for (i = 0; i < 4; i = i + 1)
audc_we[i] = {28'b0, adr_i} == ((i << 1) + 32'd1);
end
assign start_timer = (we_i && stb_i && adr_i == 9);
always @ (posedge clk_i)
if (rst) begin
poly9 <= 0;
fast_ch0 <= 0;
fast_ch2 <= 0;
ch01 <= 0;
ch23 <= 0;
fi02 <= 0;
fi13 <= 0;
base15 <= 0;
end
else
if (we_i && stb_i && adr_i == 8) begin
poly9 <= dat_i[7];
fast_ch0 <= dat_i[6];
fast_ch2 <= dat_i[5];
ch01 <= dat_i[4];
ch23 <= dat_i[3];
fi02 <= dat_i[2];
fi13 <= dat_i[1];
base15 <= dat_i[0];
end
// SKRES
always @ (posedge clk_i)
if (we_i && stb_i && adr_i == 'ha) begin
// TODO: reset SKSTAT[7:5] if they are implemented
end
always @ (posedge clk_i) begin
last_serin_rdy_i <= serin_rdy_i;
if (rst)
serin_ack_o <= 0;
else if (stb_i && !we_i && adr_i == 'hd && serin_rdy_i)
serin_ack_o <= 1;
else if (!serin_rdy_i)
serin_ack_o <= 0;
end
// SEROUT
always @ (posedge clk_i) begin
last_serout_ack_i <= serout_ack_i;
if (rst)
serout_rdy_o <= 0;
else if (we_i && stb_i && adr_i == 'hd) begin
serout <= dat_i;
serout_rdy_o <= 1;
end else if (serout_ack_i)
serout_rdy_o <= 0;
end
// IRQEN
always @ (posedge clk_i)
if (we_i && stb_i && adr_i == 'he)
irqen <= dat_i;
always @ (posedge clk_i or posedge rst_i)
if (rst_i)
rst_bits <= 0;
else
if (we_i && stb_i && adr_i == 'hf) begin
rst_bits <= dat_i[1:0];
// TODO: rest of the bits.
end
always @ (posedge clk_i) begin
last_key_pressed <= key_pressed;
last_key_break <= key_break;
end
always @ (posedge clk_i)
// IRQ_SERFIN has no latch.
irqst <= irqen & ({irqst[7:4],
!serout_ack_i && !serout_rdy_o,
irqst[2:0]} |
{key_break && !last_key_break,
key_pressed && !last_key_pressed,
serin_rdy_i && !last_serin_rdy_i,
serout_ack_i && !last_serout_ack_i,
1'b0, borrow[3], borrow[1:0]});
always @ (irqst) begin
irq = 0;
for (i = 0; i < 8; i = i + 1)
irq = irq || irqst[i];
end
pokey_basefreq u_base(rst, clk_i, base15, base);
pokey_poly4 u_poly4(rst, clk_i, poly4);
pokey_poly5 u_poly5(rst, clk_i, poly5);
pokey_poly17 u_poly17(rst, clk_i, poly9, poly17, random);
always @ (posedge clk_i) begin
poly4_shift <= {poly4_shift[2:1], poly4};
poly5_shift <= {poly5_shift[2:1], poly5};
poly17_shift <= {poly17_shift[2:1], poly17};
end
assign cnt_en[0] = fast_ch0 ? 1'b1 : base;
assign cnt_en[1] = ch01 ? borrow[0] : base;
assign cnt_en[2] = fast_ch2 ? 1'b1 : base;
assign cnt_en[3] = ch23 ? borrow[2] : base;
assign start[0] = start_timer | (ch01 ? borrow[1] : borrow[0]);
assign start[1] = start_timer | borrow[1];
assign start[2] = start_timer | (ch23 ? borrow[3] : borrow[2]);
assign start[3] = start_timer | borrow[3];
// TODO: clean it up after removing the array of instances
// (remove assignments above)
// TODO: do we need ctr_out?
pokey_counter u_ctr0(clk_i, dat_i,
audf_we[0], start[0], cnt_en[0],
ctr_out[7:0], borrow[0]);
pokey_counter u_ctr1(clk_i, dat_i,
audf_we[1], start[1], cnt_en[1],
ctr_out[15:8], borrow[1]);
pokey_counter u_ctr2(clk_i, dat_i,
audf_we[2], start[2], cnt_en[2],
ctr_out[23:16], borrow[2]);
pokey_counter u_ctr3(clk_i, dat_i,
audf_we[3], start[3], cnt_en[3],
ctr_out[31:24], borrow[3]);
pokey_audout u_audout0(start_timer, clk_i, dat_i,
audc_we[0],
poly4, poly5, poly17,
borrow[0], fi02, borrow[2],
audout0);
pokey_audout u_audout1(start_timer, clk_i, dat_i,
audc_we[1],
poly4_shift[1], poly5_shift[1], poly17_shift[1],
borrow[1], fi13, borrow[3],
audout1);
pokey_audout u_audout2(start_timer, clk_i, dat_i,
audc_we[2],
poly4_shift[2], poly5_shift[2], poly17_shift[2],
borrow[2], 1'b0, 1'b0,
audout2);
pokey_audout u_audout3(start_timer, clk_i, dat_i,
audc_we[3],
poly4_shift[3], poly5_shift[3], poly17_shift[3],
borrow[3], 1'b0, 1'b0,
audout3);
endmodule

View File

@ -0,0 +1,10 @@
Games that should work on this hardware
Anteater
Calipso
Eagle
Dambusters
Dark Planet
Lost Tomb
Tazmania
Turtles