OpenCores
URL https://opencores.org/ocsvn/psg16/psg16/trunk

Subversion Repositories psg16

[/] [psg16/] [trunk/] [rtl/] [verilog/] [PSG32.v] - Diff between revs 4 and 5

Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 5
`timescale 1ns / 1ps
`timescale 1ns / 1ps
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2007-2017  Robert Finch, Waterloo
//   \\__/ o\    (C) 2007-2017  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
// PSG32.v
// PSG32.v
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//                                                                          
//                                                                          
//
//
//      Registers
//      Registers
//  00      -------- ffffffff ffffffff ffffffff     freq [23:0]
//  00      -------- ffffffff ffffffff ffffffff     freq [23:0]
//  04      -------- -------- pppppppp pppppppp     pulse width
//  04      -------- -------- pppppppp pppppppp     pulse width
//      08          -------- -------- trsg--fo -vvvvv--         test, ringmod, sync, gate, filter, output, voice type
//      08          -------- -------- trsg-efo vvvvvv--         test, ringmod, sync, gate, filter, output, voice type
//  0C      aaaaaaaa aaaaaaaa dddddddd dddddddd     attack, decay
//  0C      -------- aaaaaaaa aaaaaaaa aaaaaaaa     attack
//  10      -------- ssssssss rrrrrrrr rrrrrrrr     sustain, release
//  10      -------- dddddddd dddddddd dddddddd     decay
//  14      -------- -------- --aaaaaa aaaaaaa-     wave table base address
//  14      -------- -------- -------- ssssssss     sustain
 
//  18      -------- rrrrrrrr rrrrrrrr rrrrrrrr     release
 
//  1C      -------- -------- --aaaaaa aaaaaaa-     wave table base address
//                                                                                      vvvvv
//                                                                                      vvvvv
//                                                                                      wnpst
//                                                                                      wnpst
//  18-2C   Voice #2
//  20-3C   Voice #2
//  30-44   Voice #3
//  40-5C   Voice #3
//  48-5C   Voice #4
//  60-7C   Voice #4
//
//
//      ...
//      ...
//      B0      -------- -------- -------- vvvvvvvv   volume (0-255)
//      B0      -------- -------- -------- ----vvvv   volume (0-255)
//      B4      nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn   osc3 oscillator 3
//      B4      nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn   osc3 oscillator 3
//      B8      -------- -------- -------- nnnnnnnn   env3 envelope 3
//      B8      -------- -------- -------- nnnnnnnn   env3 envelope 3
 
//  BC      -------- -------- -sss-sss -sss-sss   env state
//
//
//  C0-DC   -------- -------- s---kkkk kkkkkkkk   filter coefficients
//  C0-DC   -------- -------- s---kkkk kkkkkkkk   filter coefficients
//  E0-FC   -------- -------- -------- --------   reserved for more filter coefficients
//  E0-FC   -------- -------- -------- --------   reserved for more filter coefficients
//
//
//=============================================================================
//=============================================================================
 
 
module PSG32(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o,
module PSG32(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o,
        m_adr_o, m_dat_i, o
        m_adr_o, m_dat_i, o
);
);
parameter pClkDivide = 37;
parameter pClkDivide = 37;
 
 
// WISHBONE SYSCON
// WISHBONE SYSCON
input rst_i;
input rst_i;
input clk_i;                    // system clock
input clk_i;                    // system clock
// NON-WISHBONE
// NON-WISHBONE
input cs_i;             // circuit select
input cs_i;             // circuit select
// WISHBONE SLAVE
// WISHBONE SLAVE
input cyc_i;                    // cycle valid
input cyc_i;                    // cycle valid
input stb_i;                    // circuit select
input stb_i;                    // circuit select
output ack_o;
output ack_o;
input we_i;                             // write
input we_i;                             // write
input [7:0] adr_i;               // address input
input [7:0] adr_i;               // address input
input [31:0] dat_i;              // data input
input [31:0] dat_i;              // data input
output [31:0] dat_o;     // data output
output [31:0] dat_o;     // data output
 
 
// WISHBONE MASTER
// WISHBONE MASTER
output [13:0] m_adr_o;   // wave table address
output [13:0] m_adr_o;   // wave table address
input  [11:0] m_dat_i;   // wave table data input
input  [11:0] m_dat_i;   // wave table data input
 
 
output [17:0] o;
output [17:0] o;
 
 
// I/O registers
// I/O registers
reg [31:0] dat_o;
reg [31:0] dat_o;
reg [13:0] m_adr_o;
reg [13:0] m_adr_o;
 
 
reg [3:0] test;                          // test (enable note generator)
reg [3:0] test;                          // test (enable note generator)
reg [4:0] vt [3:0];                       // voice type
reg [5:0] vt [3:0];                       // voice type
reg [23:0] freq0, freq1, freq2, freq3;   // frequency control
reg [23:0] freq0, freq1, freq2, freq3;   // frequency control
reg [15:0] pw0, pw1, pw2, pw3;                   // pulse width control
reg [15:0] pw0, pw1, pw2, pw3;                   // pulse width control
reg [3:0] gate;
reg [3:0] gate;
reg [15:0] attack0, attack1, attack2, attack3;
reg [23:0] attack0, attack1, attack2, attack3;
reg [15:0] decay0, decay1, decay2, decay3;
reg [23:0] decay0, decay1, decay2, decay3;
reg [7:0] sustain0, sustain1, sustain2, sustain3;
reg [7:0] sustain0, sustain1, sustain2, sustain3;
reg [15:0] relese0, relese1, relese2, relese3;
reg [23:0] relese0, relese1, relese2, relese3;
reg [13:0] wtadr0, wtadr1, wtadr2, wtadr3;
reg [13:0] wtadr0, wtadr1, wtadr2, wtadr3;
reg [3:0] sync;
reg [3:0] sync;
reg [3:0] ringmod;
reg [3:0] ringmod;
reg [3:0] outctrl;
reg [3:0] outctrl;
reg [3:0] filt;                // 1 = output goes to filter
reg [3:0] filt;                // 1 = output goes to filter
 
reg [3:0] eg;                   // 1 = output goes through envelope generator
wire [31:0] acc0, acc1, acc2, acc3;
wire [31:0] acc0, acc1, acc2, acc3;
reg [7:0] volume;        // master volume
reg [3:0] volume;        // master volume
wire [11:0] tg1_o,tg2_o,tg3_o,tg4_o;    // tone generator output
wire [11:0] tg1_o,tg2_o,tg3_o,tg4_o;    // tone generator output
wire [7:0] env;          // envelope generator output
wire [7:0] env;          // envelope generator output
wire [7:0] env3;
wire [7:0] env0, env1, env2, env3;
wire [19:0] out0,out1,out2,out3;
wire [19:0] out0,out1,out2,out3;
wire [2:0] es0,es1,es2,es3;
wire [2:0] es0,es1,es2,es3;
wire [29:0] out4;
wire [29:0] out4;
reg [21:0] sum,fsum;
reg [21:0] sum,fsum;
reg [21:0] sum2;
reg [21:0] sum2;
wire [21:0] filtin1;     // FIR filter input
wire [21:0] filtin1;     // FIR filter input
wire [37:0] filt_o;              // FIR filter output
wire [37:0] filt_o;              // FIR filter output
reg [1:0] cnt;
reg [1:0] cnt;
reg [1:0] cnt1,cnt2,cnt3;
reg [1:0] cnt1,cnt2,cnt3;
 
 
// channel select signal
// channel select signal
wire [1:0] sel = cnt[1:0];
wire [1:0] sel = cnt[1:0];
 
 
and(cs, cyc_i, stb_i, cs_i);
and(cs, cyc_i, stb_i, cs_i);
reg ack1,ack2;
reg ack1,ack2;
always @(posedge clk_i)
always @(posedge clk_i)
        ack1 <= cs;
        ack1 <= cs;
always @(posedge clk_i)
always @(posedge clk_i)
    ack2 <= ack1 & cs;
    ack2 <= ack1 & cs;
assign ack_o = cs ? (we_i ? 1'b1 : ack2) : 1'b0;
assign ack_o = cs ? (we_i ? 1'b1 : ack2) : 1'b0;
 
 
// Register shadow ram for register readback
// Register shadow ram for register readback
reg [15:0] reg_shadow [63:0];
reg [15:0] reg_shadow [63:0];
reg [8:0] radr;
reg [8:0] radr;
always @(posedge clk_i)
always @(posedge clk_i)
    if (cs & we_i)  reg_shadow[adr_i[7:2]] <= dat_i[15:0];
    if (cs & we_i)  reg_shadow[adr_i[7:2]] <= dat_i[15:0];
always @(posedge clk_i)
always @(posedge clk_i)
    radr <= adr_i[7:2];
    radr <= adr_i[7:2];
wire [15:0] reg_shadow_o = reg_shadow[radr];
wire [15:0] reg_shadow_o = reg_shadow[radr];
 
 
// write to registers
// write to registers
always @(posedge clk_i)
always @(posedge clk_i)
begin
begin
        if (rst_i) begin
        if (rst_i) begin
                freq0 <= 0;
                freq0 <= 0;
                freq1 <= 0;
                freq1 <= 0;
                freq2 <= 0;
                freq2 <= 0;
                freq3 <= 0;
                freq3 <= 0;
                pw0 <= 0;
                pw0 <= 0;
                pw1 <= 0;
                pw1 <= 0;
                pw2 <= 0;
                pw2 <= 0;
                pw3 <= 0;
                pw3 <= 0;
                test <= 0;
                test <= 0;
                vt[0] <= 0;
                vt[0] <= 0;
                vt[1] <= 0;
                vt[1] <= 0;
                vt[2] <= 0;
                vt[2] <= 0;
                vt[3] <= 0;
                vt[3] <= 0;
                gate <= 0;
                gate <= 0;
                outctrl <= 0;
                outctrl <= 0;
                filt <= 0;
                filt <= 0;
                attack0 <= 0;
                attack0 <= 0;
                attack1 <= 0;
                attack1 <= 0;
                attack2 <= 0;
                attack2 <= 0;
                attack3 <= 0;
                attack3 <= 0;
                decay0 <= 0;
                decay0 <= 0;
                sustain0 <= 0;
                sustain0 <= 0;
                relese0 <= 0;
                relese0 <= 0;
                decay1 <= 0;
                decay1 <= 0;
                sustain1 <= 0;
                sustain1 <= 0;
                relese1 <= 0;
                relese1 <= 0;
                decay2 <= 0;
                decay2 <= 0;
                sustain2 <= 0;
                sustain2 <= 0;
                relese2 <= 0;
                relese2 <= 0;
                decay3 <= 0;
                decay3 <= 0;
                sustain3 <= 0;
                sustain3 <= 0;
                relese3 <= 0;
                relese3 <= 0;
                sync <= 0;
                sync <= 0;
                ringmod <= 0;
                ringmod <= 0;
                volume <= 0;
                volume <= 0;
        end
        end
        else begin
        else begin
                if (cs & we_i) begin
                if (cs & we_i) begin
                        case(adr_i[7:2])
                        case(adr_i[7:2])
                        //---------------------------------------------------------
                        //---------------------------------------------------------
                        6'd00:  freq0 <= dat_i[23:0];
                        6'd00:  freq0 <= dat_i[23:0];
                        6'd01:  pw0 <= dat_i[15:0];
                        6'd01:  pw0 <= dat_i[15:0];
                        6'd02:  begin
                        6'd02:  begin
                                                vt[0] <= dat_i[6:2];
                                                vt[0] <= dat_i[7:2];
                                                outctrl[0] <= dat_i[8];
                                                outctrl[0] <= dat_i[8];
                                                filt[0] <= dat_i[9];
                                                filt[0] <= dat_i[9];
 
                                                eg[0] <= dat_i[10];
                                                gate[0] <= dat_i[12];
                                                gate[0] <= dat_i[12];
                                                sync[0] <= dat_i[13];
                                                sync[0] <= dat_i[13];
                                                ringmod[0] <= dat_i[14];
                                                ringmod[0] <= dat_i[14];
                                                test[0] <= dat_i[15];
                                                test[0] <= dat_i[15];
                                        end
                                        end
                        6'd03:  begin
                        6'd03:  attack0 <= dat_i[23:0];
                                        attack0 <= dat_i[31:16];
                        6'd04:  decay0 <= dat_i[23:0];
                                        decay0 <= dat_i[15:0];
                    6'd05:  sustain0 <= dat_i[7:0];
                                        end
                        6'd06:  relese0 <= dat_i[23:0];
                    6'd04:   begin
            6'd07:  wtadr0 <= {dat_i[13:1],1'b0};
                                        relese0 <= dat_i[15:0];
 
                                        sustain0 <= dat_i[23:16];
 
                                        end
 
            6'd05:  wtadr0 <= {dat_i[13:1],1'b0};
 
 
 
                        //---------------------------------------------------------
                        //---------------------------------------------------------
                        6'd06:  freq1 <= dat_i[23:0];
                        6'd08:  freq1 <= dat_i[23:0];
                        6'd07:  pw1 <= dat_i[15:0];
                        6'd09:  pw1 <= dat_i[15:0];
                        6'd08:  begin
                        6'd10:  begin
                                                vt[1] <= dat_i[6:2];
                                                vt[1] <= dat_i[7:2];
                                                outctrl[1] <= dat_i[8];
                                                outctrl[1] <= dat_i[8];
                                                filt[1] <= dat_i[9];
                                                filt[1] <= dat_i[9];
 
                                                eg[1] <= dat_i[10];
                                                gate[1] <= dat_i[12];
                                                gate[1] <= dat_i[12];
                                                sync[1] <= dat_i[13];
                                                sync[1] <= dat_i[13];
                                                ringmod[1] <= dat_i[14];
                                                ringmod[1] <= dat_i[14];
                                                test[1] <= dat_i[15];
                                                test[1] <= dat_i[15];
                                        end
                                        end
                        6'd09:  begin
                        6'd11:  attack1 <= dat_i[23:0];
                                        attack1 <= dat_i[31:16];
            6'd12:  decay1 <= dat_i[23:0];
                                        decay1 <= dat_i[15:0];
            6'd13:  sustain1 <= dat_i[7:0];
                                        end
            6'd14:  relese1 <= dat_i[23:0];
                    6'd10:
            6'd15:  wtadr1 <= {dat_i[13:1],1'b0};
                                        begin
 
                                        relese1 <= dat_i[15:0];
 
                                        sustain1 <= dat_i[23:16];
 
                                        end
 
            6'd11:  wtadr1 <= {dat_i[13:1],1'b0};
 
 
 
                        //---------------------------------------------------------
                        //---------------------------------------------------------
                        6'd12:  freq2 <= dat_i[23:0];
                        6'd16:  freq2 <= dat_i[23:0];
                        6'd13:  pw2 <= dat_i[15:0];
                        6'd17:  pw2 <= dat_i[15:0];
                        6'd14:  begin
                        6'd18:  begin
                                                vt[2] <= dat_i[6:2];
                                                vt[2] <= dat_i[7:2];
                                                outctrl[2] <= dat_i[8];
                                                outctrl[2] <= dat_i[8];
                                                filt[2] <= dat_i[9];
                                                filt[2] <= dat_i[9];
 
                                                eg[2] <= dat_i[10];
                                                gate[2] <= dat_i[12];
                                                gate[2] <= dat_i[12];
                                                sync[2] <= dat_i[5];
                                                sync[2] <= dat_i[5];
                                                outctrl[0] <= dat_i[13];
                                                outctrl[0] <= dat_i[13];
                                                ringmod[2] <= dat_i[14];
                                                ringmod[2] <= dat_i[14];
                                                test[2] <= dat_i[15];
                                                test[2] <= dat_i[15];
                                        end
                                        end
                        6'd15:  begin
                        6'd19:  attack2 <= dat_i[23:0];
                                        attack2 <= dat_i[31:16];
            6'd20:  decay2 <= dat_i[23:0];
                                        decay2 <= dat_i[15:0];
            6'd21:  sustain2 <= dat_i[7:0];
                                        end
            6'd22:  relese2 <= dat_i[23:0];
                    6'd16:      begin
            6'd23:  wtadr2 <= {dat_i[13:1],1'b0};
                                        relese2 <= dat_i[15:0];
 
                                        sustain2 <= dat_i[23:16];
 
                                        end
 
            6'd17:  wtadr1 <= {dat_i[13:1],1'b0};
 
 
 
                        //---------------------------------------------------------
                        //---------------------------------------------------------
                        6'd18:  freq3 <= dat_i[23:0];
                        6'd24:  freq3 <= dat_i[23:0];
                        6'd19:  pw3 <= dat_i[15:0];
                        6'd25:  pw3 <= dat_i[15:0];
                        6'd20:  begin
                        6'd26:  begin
                                                vt[3] <= dat_i[6:2];
                                                vt[3] <= dat_i[7:2];
                                                outctrl[3] <= dat_i[8];
                                                outctrl[3] <= dat_i[8];
                                                filt[3] <= dat_i[9];
                                                filt[3] <= dat_i[9];
 
                                                eg[3] <= dat_i[10];
                                                gate[3] <= dat_i[12];
                                                gate[3] <= dat_i[12];
                                                sync[3] <= dat_i[13];
                                                sync[3] <= dat_i[13];
                                                ringmod[3] <= dat_i[14];
                                                ringmod[3] <= dat_i[14];
                                                test[3] <= dat_i[15];
                                                test[3] <= dat_i[15];
                                        end
                                        end
                        6'd21:  begin
                        6'd27:  attack3 <= dat_i[23:0];
                                        attack3 <= dat_i[31:16];
            6'd28:  decay3 <= dat_i[23:0];
                                        decay3 <= dat_i[15:0];
            6'd29:  sustain3 <= dat_i[7:0];
                                        relese3 <= dat_i[15:0];
            6'd30:  relese3 <= dat_i[23:0];
                                        sustain3 <= dat_i[23:16];
            6'd31:  wtadr3 <= {dat_i[13:1],1'b0};
                                        end
 
            6'd22:  wtadr1 <= {dat_i[13:1],1'b0};
 
 
 
                        //---------------------------------------------------------
                        //---------------------------------------------------------
                        6'd44:  volume <= dat_i[7:0];
                        6'd44:  volume <= dat_i[3:0];
 
 
                        default:        ;
                        default:        ;
                        endcase
                        endcase
                end
                end
        end
        end
end
end
 
 
 
 
always @(posedge clk_i)
always @(posedge clk_i)
    case(adr_i[7:2])
    case(adr_i[7:2])
    6'd45:      begin
    6'd45:      begin
            dat_o <= acc3;
            dat_o <= acc3;
            end
            end
    6'd45:      begin
    6'd46:      begin
            dat_o <= {24'h0,env3};
            dat_o <= {24'h0,env3};
            end
            end
    6'd46:  dat_o <= {17'h0,es3,1'b0,es2,1'b0,es1,1'b0,es0};
    6'd47:  dat_o <= {17'h0,es3,1'b0,es2,1'b0,es1,1'b0,es0};
    default: begin
    default: begin
            dat_o <= reg_shadow_o;
            dat_o <= reg_shadow_o;
            end
            end
    endcase
    endcase
 
 
wire [13:0] madr;
wire [13:0] madr;
mux4to1 #(12) u11
mux4to1 #(12) u11
(
(
        .e(1'b1),
        .e(1'b1),
        .s(cnt),
        .s(cnt),
        .i0(wtadr0 + {acc0[27:17],1'b0}),
        .i0(wtadr0 + {acc0[27:17],1'b0}),
        .i1(wtadr1 + {acc1[27:17],1'b0}),
        .i1(wtadr1 + {acc1[27:17],1'b0}),
        .i2(wtadr2 + {acc2[27:17],1'b0}),
        .i2(wtadr2 + {acc2[27:17],1'b0}),
        .i3(wtadr3 + {acc3[27:17],1'b0}),
        .i3(wtadr3 + {acc3[27:17],1'b0}),
        .z(madr)
        .z(madr)
);
);
always @(posedge clk_i)
always @(posedge clk_i)
    m_adr_o <= madr;
    m_adr_o <= madr;
 
wire [11:0] wave_i = m_dat_i;
 
 
// This counter controls channel multiplexing for the wave table
// This counter controls channel multiplexing for the wave table
always @(posedge clk_i)
always @(posedge clk_i)
if (rst_i)
if (rst_i)
    cnt <= 2'd0;
    cnt <= 2'd0;
else
else
    cnt <= cnt + 2'd1;
    cnt <= cnt + 2'd1;
 
 
// note generator - multi-channel
// note generator - multi-channel
PSGToneGenerator u1a
PSGToneGenerator u1a
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .ack(cnt==2'b11),
    .ack(cnt==2'b11),
    .test(test[0]),
    .test(test[0]),
    .vt(vt[0]),
    .vt(vt[0]),
    .freq(freq0),
    .freq(freq0),
    .pw(pw0),
    .pw(pw0),
    .acc(acc0),
    .acc(acc0),
    .prev_acc(acc3),
    .prev_acc(acc3),
    .wave(wave_i),
    .wave(wave_i),
    .sync(sync[0]),
    .sync(sync[0]),
    .ringmod(ringmod[0]),
    .ringmod(ringmod[0]),
    .o(tg1_o)
    .o(tg1_o)
);
);
 
 
PSGToneGenerator u1b
PSGToneGenerator u1b
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .ack(cnt==2'b00),
    .ack(cnt==2'b00),
    .test(test[1]),
    .test(test[1]),
    .vt(vt[1]),
    .vt(vt[1]),
    .freq(freq1),
    .freq(freq1),
    .pw(pw1),
    .pw(pw1),
    .acc(acc1),
    .acc(acc1),
    .prev_acc(acc0),
    .prev_acc(acc0),
    .wave(wave_i),
    .wave(wave_i),
    .sync(sync[1]),
    .sync(sync[1]),
    .ringmod(ringmod[1]),
    .ringmod(ringmod[1]),
    .o(tg2_o)
    .o(tg2_o)
);
);
 
 
PSGToneGenerator u1c
PSGToneGenerator u1c
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .ack(cnt==2'b01),
    .ack(cnt==2'b01),
    .test(test[2]),
    .test(test[2]),
    .vt(vt[2]),
    .vt(vt[2]),
    .freq(freq2),
    .freq(freq2),
    .pw(pw2),
    .pw(pw2),
    .acc(acc2),
    .acc(acc2),
    .prev_acc(acc1),
    .prev_acc(acc1),
    .wave(wave_i),
    .wave(wave_i),
    .sync(sync[2]),
    .sync(sync[2]),
    .ringmod(ringmod[2]),
    .ringmod(ringmod[2]),
    .o(tg3_o)
    .o(tg3_o)
);
);
 
 
PSGToneGenerator u1d
PSGToneGenerator u1d
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .ack(cnt==2'b10),
    .ack(cnt==2'b10),
    .test(test[3]),
    .test(test[3]),
    .vt(vt[3]),
    .vt(vt[3]),
    .freq(freq3),
    .freq(freq3),
    .pw(pw3),
    .pw(pw3),
    .acc(acc3),
    .acc(acc3),
    .prev_acc(acc2),
    .prev_acc(acc2),
    .wave(wave_i),
    .wave(wave_i),
    .sync(sync[3]),
    .sync(sync[3]),
    .ringmod(ringmod[3]),
    .ringmod(ringmod[3]),
    .o(tg4_o)
    .o(tg4_o)
);
);
 
 
PSGEnvelopeGenerator u2a
PSGEnvelopeGenerator u2a
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .gate(gate[0]),
    .gate(gate[0]),
    .attack(attack0),
    .attack(attack0),
    .decay(decay0),
    .decay(decay0),
    .sustain(sustain0),
    .sustain(sustain0),
    .relese(relese0),
    .relese(relese0),
    .o(env0),
    .o(env0),
    .envState(es0)
    .envState(es0)
);
);
 
 
PSGEnvelopeGenerator u2b
PSGEnvelopeGenerator u2b
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .gate(gate[1]),
    .gate(gate[1]),
    .attack(attack1),
    .attack(attack1),
    .decay(decay1),
    .decay(decay1),
    .sustain(sustain1),
    .sustain(sustain1),
    .relese(relese1),
    .relese(relese1),
    .o(env1),
    .o(env1),
    .envState(es1)
    .envState(es1)
);
);
 
 
PSGEnvelopeGenerator u2c
PSGEnvelopeGenerator u2c
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .gate(gate[2]),
    .gate(gate[2]),
    .attack(attack2),
    .attack(attack2),
    .decay(decay2),
    .decay(decay2),
    .sustain(sustain2),
    .sustain(sustain2),
    .relese(relese2),
    .relese(relese2),
    .o(env2),
    .o(env2),
    .envState(es2)
    .envState(es2)
);
);
 
 
PSGEnvelopeGenerator u2d
PSGEnvelopeGenerator u2d
(
(
    .rst(rst_i),
    .rst(rst_i),
    .clk(clk_i),
    .clk(clk_i),
    .gate(gate[3]),
    .gate(gate[3]),
    .attack(attack3),
    .attack(attack3),
    .decay(decay3),
    .decay(decay3),
    .sustain(sustain3),
    .sustain(sustain3),
    .relese(relese3),
    .relese(relese3),
    .o(env3),
    .o(env3),
    .envState(es3)
    .envState(es3)
);
);
 
 
// shape output according to envelope
// shape output according to envelope
PSGShaper u5a
PSGShaper u5a
(
(
        .clk_i(clk_i),
        .clk_i(clk_i),
        .ce(1'b1),
        .ce(1'b1),
        .tgi(tg1_o),
        .tgi(tg1_o),
        .env(env0),
        .env(eg[0] ? env0 : 8'hFF),
        .o(out0)
        .o(out0)
);
);
 
 
PSGShaper u5b
PSGShaper u5b
(
(
        .clk_i(clk_i),
        .clk_i(clk_i),
        .ce(1'b1),
        .ce(1'b1),
        .tgi(tg2_o),
        .tgi(tg2_o),
        .env(env1),
        .env(eg[1] ? env1 : 8'hFF),
        .o(out1)
        .o(out1)
);
);
 
 
PSGShaper u5c
PSGShaper u5c
(
(
        .clk_i(clk_i),
        .clk_i(clk_i),
        .ce(1'b1),
        .ce(1'b1),
        .tgi(tg3_o),
        .tgi(tg3_o),
        .env(env2),
        .env(eg[2] ? env2 : 8'hFF),
        .o(out2)
        .o(out2)
);
);
 
 
PSGShaper u5d
PSGShaper u5d
(
(
        .clk_i(clk_i),
        .clk_i(clk_i),
        .ce(1'b1),
        .ce(1'b1),
        .tgi(tg4_o),
        .tgi(tg4_o),
        .env(env3),
        .env(eg[3] ? env3 : 8'hFF),
        .o(out3)
        .o(out3)
);
);
 
 
always @(posedge clk_i)
always @(posedge clk_i)
        cnt1 <= cnt;
        cnt1 <= cnt;
always @(posedge clk_i)
always @(posedge clk_i)
        cnt2 <= cnt1;
        cnt2 <= cnt1;
always @(posedge clk_i)
always @(posedge clk_i)
        cnt3 <= cnt2;
        cnt3 <= cnt2;
 
 
// Sum the channels not going to the filter
// Sum the channels not going to the filter
always @(posedge clk_i)
always @(posedge clk_i)
sum <=
sum <=
    {2'd0,(out0 & {20{outctrl[0]}})} +
    {2'd0,(out0 & {20{outctrl[0]}})} +
    {2'd0,(out1 & {20{outctrl[1]}})} +
    {2'd0,(out1 & {20{outctrl[1]}})} +
    {2'd0,(out2 & {20{outctrl[2]}})} +
    {2'd0,(out2 & {20{outctrl[2]}})} +
    {2'd0,(out3 & {20{outctrl[3]}})};
    {2'd0,(out3 & {20{outctrl[3]}})};
 
 
// Sum the channels going to the filter
// Sum the channels going to the filter
always @(posedge clk_i)
always @(posedge clk_i)
fsum <=
fsum <=
    {2'd0,(out0 & {20{filt[0]}})} +
    {2'd0,(out0 & {20{filt[0]}})} +
    {2'd0,(out1 & {20{filt[1]}})} +
    {2'd0,(out1 & {20{filt[1]}})} +
    {2'd0,(out2 & {20{filt[2]}})} +
    {2'd0,(out2 & {20{filt[2]}})} +
    {2'd0,(out3 & {20{filt[3]}})};
    {2'd0,(out3 & {20{filt[3]}})};
 
 
// The FIR filter
// The FIR filter
PSGFilter2 u8
PSGFilter2 u8
(
(
        .rst(rst_i),
        .rst(rst_i),
        .clk(clk_i),
        .clk(clk_i),
        .cnt(cnt2),
        .cnt(cnt2),
        .wr(we_i && stb_i && adr_i[7:6]==3'b11),
        .wr(we_i && stb_i && adr_i[7:6]==3'b11),
    .adr(adr_i[5:2]),
    .adr(adr_i[5:2]),
    .din({dat_i[15],dat_i[11:0]}),
    .din({dat_i[15],dat_i[11:0]}),
    .i(fsum),
    .i(fsum),
    .o(filt_o)
    .o(filt_o)
);
);
 
 
// Sum the filtered and unfiltered output
// Sum the filtered and unfiltered output
always @(posedge clk_i)
always @(posedge clk_i)
        sum2 <= sum + filt_o[37:16];
        sum2 <= sum + filt_o[37:16];
 
 
// Last stage:
// Last stage:
// Adjust output according to master volume
// Adjust output according to master volume
PSGVolumeControl u10
PSGVolumeControl u10
(
(
        .rst_i(rst_i),
        .rst_i(rst_i),
        .clk_i(clk_i),
        .clk_i(clk_i),
        .i(sum2),
        .i(sum2),
        .volume(volume),
        .volume(volume),
        .o(out4)
        .o(out4)
);
);
 
 
assign o = out4[29:12];
assign o = out4[29:12];
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.