Finally get Sound every Time
@ -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
|
||||
@ -14,4 +14,4 @@
|
||||
-- SPACE : Fire
|
||||
-- ARROW KEYS : Movements
|
||||
---------------------------------------------------------------------------------
|
||||
Todo: Sound and Joystick
|
||||
Todo: Joystick(Fire)
|
||||
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 394 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 425 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 404 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 426 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 402 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 439 KiB |
@ -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)
|
||||
);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -1,2 +1,2 @@
|
||||
`define BUILD_DATE "181124"
|
||||
`define BUILD_TIME "140415"
|
||||
`define BUILD_DATE "181218"
|
||||
`define BUILD_TIME "170839"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
10
Arcade_MiST/Galaxian Hardware/ReadMe.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Games that should work on this hardware
|
||||
|
||||
Anteater
|
||||
Calipso
|
||||
Eagle
|
||||
Dambusters
|
||||
Dark Planet
|
||||
Lost Tomb
|
||||
Tazmania
|
||||
Turtles
|
||||