📄 sound.v
字号:
//
// FPGA PACMAN waveform sound
//
// Version : beta2
//
// Copyright(c) 2002,2003 Tatsuyuki Satoh , All rights reserved
//
// Important !
//
// This program is freeware for non-commercial use.
// An author does no guarantee about this program.
// You can use this under your own risk.
//
// 2003. 2. 6 beta2 rewrite for minimize
// export waveform ROM
// suound mute logic
//
module sound(
AB,DI,WR0,WR1,PCLK,SOUND_ON,HC,DAO,
// SA,S0W,S1W,S0DI,S1DI,S0DO,S1DO,
WA,WDI
);
input [3:0] AB;
input [3:0] DI;
input WR0;
input WR1;
input PCLK; // 2 x HC[0]
input SOUND_ON;
input [5:0] HC;
// DAC output with one cycle LPF.
output [9:0] DAO;
// Sound Register RAM I/F
//output [3:0] SA;
//output S0W,S1W;
//output [3:0] S0DO,S1DO;
//input [3:0] S0DI,S1DI;
// Sound WaveFormROM I/F
output [8:0] WA;
input [3:0] WDI;
//
// sampling rate : 3072000/32 =96KHz
//
// part 2K sound accumurator & waveform select RAM
reg [3:0] snd_ram0[15:0]; //acc0,wav0,acc1,wav1,acc2,wav2
// part 2L sound frequency & volume select RAM
reg [3:0] snd_ram1[15:0]; //frq0,vol0,frq0,vol1,frq2,vol2
// part 3L : sound RAM address selector
wire [3:0] regram_a = HC[1] ? HC[5:2] : AB;
// part 1L accumerator latch
reg [5:0] acc_latch;
// part 1K 4bit full adder w. carry
wire [4:0] acc_out = {1'b0,snd_ram0[regram_a]} + {1'b0,snd_ram1[regram_a]} + {4'b0,acc_latch[5]};
// part 3M timming rom
// D0 : accumurator latch
// D1 : ACC/WAV RAM write enable
// D2 : sound output latch
// D3 : accumurator clear
wire ch1_end = (HC[5:2]==4'h5);
wire ch2_end = (HC[5:2]==4'ha);
wire ch3_end = (HC[5:2]==4'hf);
wire acc_clr = ch1_end|ch2_end|ch3_end;
//
// sound generator
//
reg [3:0] vol;
reg [6:0] wav;
reg [9:0] pcm_acc,pcm_out;
always @(posedge PCLK)
begin
if(~HC[1])
begin // CPU bus cycle
// addr 5040-504f
if(WR0)
snd_ram0[regram_a] <= DI;
// addr 5050-505f
if(WR1)
snd_ram1[regram_a] <= DI;
end else begin // video bus cycle
if(~HC[0])
begin
// calcrate accumerator
if(~acc_clr)
acc_latch <= {acc_out,acc_latch[4]};
end else begin
if(acc_clr)
begin
// update wave & volume
acc_latch <= 6'b000000;
// latch wave & volume level to PCM accumurator
wav <= { 3'b000,WDI };
vol <= snd_ram1[regram_a];
end else begin
// update accumerator
snd_ram0[regram_a] <= acc_latch[4:1];
end
// update PCM outout
if(ch1_end)
begin
// update mixed PCM value
pcm_out <= pcm_acc;
pcm_acc <= 0;
end
end
end
// PCM & LPF calcrate
// pcm_acc += (wav * vol) : need 4 clock to done
if(vol[0]) // 1bit multiplexer
pcm_acc <= pcm_acc + wav;
if(~acc_clr)
begin
vol <= { 1'b0 , vol[3:1] }; // shift down
wav <= { wav[5:0] , 1'b0}; // shift up
end
end
//
// sound ROM Address
//
assign WA = { snd_ram0[regram_a] , acc_latch[4:0] };
//
// output
//
// HC[5] = 192KHz
assign DAO = SOUND_ON ? pcm_out : 8'h00;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -