mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-03-09 20:18:22 +00:00
new Soundcores on Common
This commit is contained in:
@@ -225,7 +225,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name SMART_RECOMPILE ON
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84_MiST.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/TimePilot84_CPU.sv
|
||||
@@ -244,4 +243,5 @@ set_global_assignment -name SIGNALTAP_FILE output_files/char.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/cpu.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/sdram.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/spr.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -197,7 +197,7 @@ dac #(
|
||||
dac_l(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i(audio_ch2),
|
||||
.dac_i(audio_ch1),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
@@ -206,12 +206,11 @@ dac #(
|
||||
dac_r(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i(audio_ch1),
|
||||
.dac_i(audio_ch2),
|
||||
.dac_o(AUDIO_R)
|
||||
);
|
||||
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
arcade_inputs inputs (
|
||||
@@ -220,13 +219,10 @@ arcade_inputs inputs (
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
//.rotate ( rotate ),
|
||||
//.orientation ( orientation ),
|
||||
.joyswap ( status[6] ),
|
||||
.oneplayer ( 1'b1 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
.player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -92,7 +92,7 @@ always @(posedge clk_cpu)
|
||||
else
|
||||
timer_div <= 14'hff;
|
||||
|
||||
irq_timer
|
||||
// irq_timer
|
||||
always @(posedge clk_cpu)
|
||||
if (sys_cs && cpu_we && AB[2:0] == 3'h3)
|
||||
irq_timer <= cpu_dout;
|
||||
@@ -239,7 +239,7 @@ always @(posedge clk_sys)
|
||||
//);
|
||||
|
||||
assign cpu_rom_addr = rom_addr;
|
||||
assign rom_dout = rom_cs ? cpu_rom_data : 8'hff;
|
||||
assign rom_dout = cpu_rom_data;
|
||||
|
||||
|
||||
ram88 wram(
|
||||
@@ -330,5 +330,4 @@ cpu_65c02 cpu(
|
||||
.RDY(cpu_rdy)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
8
common/Sound/JT49/jt49.qip
Normal file
8
common/Sound/JT49/jt49.qip
Normal file
@@ -0,0 +1,8 @@
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_bus.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_cen.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_div.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_eg.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_exp.v]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_noise.v]
|
||||
|
||||
224
common/Sound/JT49/jt49.v
Normal file
224
common/Sound/JT49/jt49.v
Normal file
@@ -0,0 +1,224 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
module jt49 ( // note that input ports are not multiplexed
|
||||
input rst_n,
|
||||
input clk, // signal on positive edge
|
||||
input clk_en,
|
||||
input [3:0] addr,
|
||||
input cs_n,
|
||||
input wr_n, // write
|
||||
input [7:0] din,
|
||||
input sel, // if sel is low, the clock is divided by 2
|
||||
output reg [7:0] dout,
|
||||
output reg [7:0] A, // linearised channel output
|
||||
output reg [7:0] B,
|
||||
output reg [7:0] C
|
||||
);
|
||||
|
||||
parameter [1:0] COMP=2'b00;
|
||||
parameter CLKDIV=3;
|
||||
wire [1:0] comp = COMP;
|
||||
|
||||
reg [7:0] regarray[15:0];
|
||||
|
||||
wire [4:0] envelope;
|
||||
wire bitA, bitB, bitC;
|
||||
wire noise;
|
||||
reg Amix, Bmix, Cmix;
|
||||
|
||||
wire cen16, cen256;
|
||||
|
||||
jt49_cen #(.CLKDIV(CLKDIV)) u_cen(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.cen ( clk_en ),
|
||||
.sel ( sel ),
|
||||
.cen16 ( cen16 ),
|
||||
.cen256 ( cen256 )
|
||||
);
|
||||
|
||||
// internal modules operate at clk/16
|
||||
jt49_div #(12) u_chA(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.cen ( cen16 ),
|
||||
.period ( {regarray[1][3:0], regarray[0][7:0] } ),
|
||||
.div ( bitA )
|
||||
);
|
||||
|
||||
jt49_div #(12) u_chB(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.cen ( cen16 ),
|
||||
.period ( {regarray[3][3:0], regarray[2][7:0] } ),
|
||||
.div ( bitB )
|
||||
);
|
||||
|
||||
jt49_div #(12) u_chC(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.cen ( cen16 ),
|
||||
.period ( {regarray[5][3:0], regarray[4][7:0] } ),
|
||||
.div ( bitC )
|
||||
);
|
||||
|
||||
jt49_noise u_ng(
|
||||
.clk ( clk ),
|
||||
.cen ( cen16 ),
|
||||
.rst_n ( rst_n ),
|
||||
.period ( regarray[6][4:0] ),
|
||||
.noise ( noise )
|
||||
);
|
||||
|
||||
// envelope generator
|
||||
wire eg_step;
|
||||
wire [15:0] eg_period = {regarray[4'hc],regarray[4'hb]};
|
||||
wire null_period = eg_period == 16'h0;
|
||||
|
||||
jt49_div #(16) u_envdiv(
|
||||
.clk ( clk ),
|
||||
.cen ( cen256 ),
|
||||
.rst_n ( rst_n ),
|
||||
.period ( eg_period ),
|
||||
.div ( eg_step )
|
||||
);
|
||||
|
||||
reg eg_restart;
|
||||
|
||||
jt49_eg u_env(
|
||||
.clk ( clk ),
|
||||
.cen ( cen256 ),
|
||||
.step ( eg_step ),
|
||||
.rst_n ( rst_n ),
|
||||
.restart ( eg_restart ),
|
||||
.null_period( null_period ),
|
||||
.ctrl ( regarray[4'hD][3:0] ),
|
||||
.env ( envelope )
|
||||
);
|
||||
|
||||
reg [4:0] logA, logB, logC, log;
|
||||
wire [7:0] lin;
|
||||
|
||||
jt49_exp u_exp(
|
||||
.clk ( clk ),
|
||||
.comp ( comp ),
|
||||
.din ( log ),
|
||||
.dout ( lin )
|
||||
);
|
||||
|
||||
wire [4:0] volA = { regarray[ 8][3:0], regarray[ 8][3] };
|
||||
wire [4:0] volB = { regarray[ 9][3:0], regarray[ 9][3] };
|
||||
wire [4:0] volC = { regarray[10][3:0], regarray[10][3] };
|
||||
wire use_envA = regarray[ 8][4];
|
||||
wire use_envB = regarray[ 9][4];
|
||||
wire use_envC = regarray[10][4];
|
||||
wire use_noA = regarray[ 7][3];
|
||||
wire use_noB = regarray[ 7][4];
|
||||
wire use_noC = regarray[ 7][5];
|
||||
|
||||
reg [3:0] acc_st;
|
||||
|
||||
always @(posedge clk) if( clk_en ) begin
|
||||
Amix <= (noise|use_noA) & (bitA|regarray[7][0]);
|
||||
Bmix <= (noise|use_noB) & (bitB|regarray[7][1]);
|
||||
Cmix <= (noise|use_noC) & (bitC|regarray[7][2]);
|
||||
|
||||
logA <= !Amix ? 5'd0 : (use_envA ? envelope : volA );
|
||||
logB <= !Bmix ? 5'd0 : (use_envB ? envelope : volB );
|
||||
logC <= !Cmix ? 5'd0 : (use_envC ? envelope : volC );
|
||||
end
|
||||
|
||||
always @(posedge clk, negedge rst_n) begin
|
||||
if( !rst_n ) begin
|
||||
acc_st <= 4'b1;
|
||||
A <= 8'd0;
|
||||
B <= 8'd0;
|
||||
C <= 8'd0;
|
||||
end else if(clk_en) begin
|
||||
acc_st <= { acc_st[2:0], acc_st[3] };
|
||||
case( acc_st )
|
||||
4'b0001: begin
|
||||
log <= logA;
|
||||
end
|
||||
4'b0010: begin
|
||||
A <= lin;
|
||||
log <= logB;
|
||||
end
|
||||
4'b0100: begin
|
||||
B <= lin;
|
||||
log <= logC;
|
||||
end
|
||||
4'b1000: begin // last sum
|
||||
C <= lin;
|
||||
end
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
reg [7:0] read_mask;
|
||||
|
||||
always @(*)
|
||||
case(addr)
|
||||
4'h0,4'h2,4'h4,4'h7,4'hb,4'hc,4'he,4'hf:
|
||||
read_mask = 8'hff;
|
||||
4'h1,4'h3,4'h5,4'hd:
|
||||
read_mask = 8'h0f;
|
||||
4'h6,4'h8,4'h9,4'ha:
|
||||
read_mask = 8'h1f;
|
||||
endcase // addr
|
||||
|
||||
// register array
|
||||
wire write;
|
||||
reg last_write;
|
||||
wire wr_edge = write & ~last_write;
|
||||
|
||||
assign write = !wr_n && !cs_n;
|
||||
|
||||
always @(posedge clk, negedge rst_n) begin
|
||||
if( !rst_n ) begin
|
||||
dout <= 8'd0;
|
||||
last_write <= 0;
|
||||
eg_restart <= 0;
|
||||
regarray[0]<=8'd0; regarray[4]<=8'd0; regarray[ 8]<=8'd0; regarray[12]<=8'd0;
|
||||
regarray[1]<=8'd0; regarray[5]<=8'd0; regarray[ 9]<=8'd0; regarray[13]<=8'd0;
|
||||
regarray[2]<=8'd0; regarray[6]<=8'd0; regarray[10]<=8'd0; regarray[14]<=8'd0;
|
||||
regarray[3]<=8'd0; regarray[7]<=8'd0; regarray[11]<=8'd0; regarray[15]<=8'd0;
|
||||
end else begin
|
||||
last_write <= write;
|
||||
// Data read
|
||||
case( addr )
|
||||
default: dout <= regarray[ addr ] & read_mask;
|
||||
endcase
|
||||
// Data write
|
||||
if( write ) begin
|
||||
regarray[addr] <= din;
|
||||
if ( addr == 4'hD && wr_edge ) eg_restart <= 1;
|
||||
end else begin
|
||||
eg_restart <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
87
common/Sound/JT49/jt49_bus.v
Normal file
87
common/Sound/JT49/jt49_bus.v
Normal file
@@ -0,0 +1,87 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 28-Jan-2019
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
// This is a wrapper with the BDIR/BC1 pins
|
||||
|
||||
module jt49_bus ( // note that input ports are not multiplexed
|
||||
input rst_n,
|
||||
input clk, // signal on positive edge
|
||||
input clk_en,
|
||||
// bus control pins of original chip
|
||||
input bdir,
|
||||
input bc1,
|
||||
input [7:0] din,
|
||||
|
||||
input sel, // if sel is low, the clock is divided by 2
|
||||
output [7:0] dout,
|
||||
output [7:0] A, // linearised channel output
|
||||
output [7:0] B,
|
||||
output [7:0] C
|
||||
);
|
||||
|
||||
parameter [1:0] COMP=2'b00;
|
||||
|
||||
reg wr_n, cs_n;
|
||||
reg [3:0] addr;
|
||||
reg addr_ok;
|
||||
reg [7:0] din_latch;
|
||||
|
||||
always @(posedge clk)
|
||||
if( !rst_n ) begin
|
||||
wr_n <= 1'b1;
|
||||
cs_n <= 1'b1;
|
||||
addr <= 4'd0;
|
||||
addr_ok <= 1'b1;
|
||||
end else begin // I/O cannot use clk_en
|
||||
// addr must be
|
||||
case( {bdir,bc1} )
|
||||
2'b00: { wr_n, cs_n } <= 2'b11;
|
||||
2'b01: { wr_n, cs_n } <= addr_ok ? 2'b10 : 2'b11;
|
||||
2'b10: begin
|
||||
{ wr_n, cs_n } <= addr_ok ? 2'b00 : 2'b11;
|
||||
din_latch <= din;
|
||||
end
|
||||
2'b11: begin
|
||||
{ wr_n, cs_n } <= 2'b11;
|
||||
addr <= din[3:0];
|
||||
addr_ok <= din[7:4] == 4'd0;
|
||||
end
|
||||
endcase // {bdir,bc1}
|
||||
end
|
||||
|
||||
jt49 #(.COMP(COMP)) u_jt49( // note that input ports are not multiplexed
|
||||
.rst_n ( rst_n ),
|
||||
.clk ( clk ), // signal on positive edge
|
||||
.clk_en ( clk_en ), // clock enable on negative edge
|
||||
.addr ( addr[3:0] ),
|
||||
.cs_n ( cs_n ),
|
||||
.wr_n ( wr_n ), // write
|
||||
.din ( din_latch ),
|
||||
.sel ( sel ), // if sel is low, the clock is divided by 2
|
||||
.dout ( dout ),
|
||||
.A ( A ), // linearised channel output
|
||||
.B ( B ),
|
||||
.C ( C )
|
||||
);
|
||||
|
||||
endmodule // jt49_bus
|
||||
56
common/Sound/JT49/jt49_cen.v
Normal file
56
common/Sound/JT49/jt49_cen.v
Normal file
@@ -0,0 +1,56 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
module jt49_cen(
|
||||
input clk,
|
||||
input rst_n,
|
||||
input cen, // base clock enable signal
|
||||
input sel, // when low, divide by 2 once more
|
||||
output reg cen16,
|
||||
output reg cen256
|
||||
);
|
||||
|
||||
parameter CLKDIV = 3; // use 3 for standalone JT49 or 2
|
||||
|
||||
reg [CLKDIV:0] cencnt;
|
||||
localparam eg = CLKDIV; //8;
|
||||
|
||||
wire toggle16 = sel ? ~|cencnt[CLKDIV-1:0] : ~|cencnt[CLKDIV:0];
|
||||
wire toggle256= sel ? ~|cencnt[eg-2:0] : ~|cencnt[eg-1:0];
|
||||
|
||||
|
||||
always @(posedge clk, negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
cencnt <= 1'd0;
|
||||
else begin
|
||||
if(cen) cencnt <= cencnt+1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cen16 <= cen & toggle16;
|
||||
cen256 <= cen & toggle256;
|
||||
end
|
||||
|
||||
|
||||
endmodule // jt49_cen
|
||||
53
common/Sound/JT49/jt49_div.v
Normal file
53
common/Sound/JT49/jt49_div.v
Normal file
@@ -0,0 +1,53 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module jt49_div #(parameter W=12 )
|
||||
(
|
||||
input wire clk, // this is the divided down clock from the core
|
||||
input wire cen,
|
||||
input wire rst_n,
|
||||
input wire[W-1:0] period,
|
||||
output reg div
|
||||
);
|
||||
|
||||
reg [W-1:0]count;
|
||||
|
||||
wire [W-1:0] one = { {W-1{1'b0}}, 1'b1};
|
||||
|
||||
always @(posedge clk, negedge rst_n ) begin
|
||||
if( !rst_n) begin
|
||||
count <= one;
|
||||
div <= 1'b0;
|
||||
end
|
||||
else if(cen) begin
|
||||
if( count>=period ) begin
|
||||
count <= one;
|
||||
div <= ~div;
|
||||
end
|
||||
else
|
||||
/*if( period!={W{1'b0}} )*/ count <= count + one ;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
88
common/Sound/JT49/jt49_eg.v
Normal file
88
common/Sound/JT49/jt49_eg.v
Normal file
@@ -0,0 +1,88 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
module jt49_eg(
|
||||
input wire cen,
|
||||
input wire clk, // this is the divided down clock from the core
|
||||
input wire step,
|
||||
input wire null_period,
|
||||
input wire rst_n,
|
||||
input wire restart,
|
||||
input wire[3:0] ctrl,
|
||||
output reg [4:0] env
|
||||
);
|
||||
|
||||
reg inv, stop;
|
||||
reg [4:0] gain;
|
||||
|
||||
wire CONT = ctrl[3];
|
||||
wire ATT = ctrl[2];
|
||||
wire ALT = ctrl[1];
|
||||
wire HOLD = ctrl[0];
|
||||
|
||||
wire will_hold = !CONT || HOLD;
|
||||
|
||||
always @(posedge clk)
|
||||
if( cen ) env <= inv ? ~gain : gain;
|
||||
|
||||
reg last_step;
|
||||
wire step_edge = (step && !last_step) || null_period;
|
||||
wire will_invert = (!CONT&&ATT) || (CONT&&ALT);
|
||||
reg rst_latch, rst_clr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if( restart ) rst_latch <= 1;
|
||||
else if(rst_clr ) rst_latch <= 0;
|
||||
end
|
||||
|
||||
always @( posedge clk, negedge rst_n )
|
||||
if( !rst_n) begin
|
||||
gain <= 5'h1F;
|
||||
inv <= 0;
|
||||
stop <= 0;
|
||||
rst_clr <= 0;
|
||||
end
|
||||
else if( cen ) begin
|
||||
last_step <= step;
|
||||
if( rst_latch ) begin
|
||||
gain <= 5'h1F;
|
||||
inv <= ATT;
|
||||
stop <= 1'b0;
|
||||
rst_clr <= 1;
|
||||
end
|
||||
else begin
|
||||
rst_clr <= 0;
|
||||
if (step_edge && !stop) begin
|
||||
if( gain==5'h00 ) begin
|
||||
if( will_hold )
|
||||
stop <= 1'b1;
|
||||
else
|
||||
gain <= gain-5'b1;
|
||||
if( will_invert ) inv<=~inv;
|
||||
end
|
||||
else gain <= gain-5'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
174
common/Sound/JT49/jt49_exp.v
Normal file
174
common/Sound/JT49/jt49_exp.v
Normal file
@@ -0,0 +1,174 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
// Compression vs dynamic range
|
||||
// 0 -> 43.6dB
|
||||
// 1 -> 29.1
|
||||
// 2 -> 21.8
|
||||
// 3 -> 13.4
|
||||
|
||||
module jt49_exp(
|
||||
input wire clk,
|
||||
input wire[1:0] comp, // compression
|
||||
input wire[4:0] din,
|
||||
output reg [7:0] dout
|
||||
);
|
||||
|
||||
reg [7:0] lut[0:127];
|
||||
wire[6:0] addr = {comp,din};
|
||||
always @(posedge clk) dout <= lut[addr];
|
||||
|
||||
initial begin
|
||||
lut[0] = 8'd0;
|
||||
lut[1] = 8'd1;
|
||||
lut[2] = 8'd1;
|
||||
lut[3] = 8'd1;
|
||||
lut[4] = 8'd2;
|
||||
lut[5] = 8'd2;
|
||||
lut[6] = 8'd3;
|
||||
lut[7] = 8'd3;
|
||||
lut[8] = 8'd4;
|
||||
lut[9] = 8'd5;
|
||||
lut[10] = 8'd6;
|
||||
lut[11] = 8'd7;
|
||||
lut[12] = 8'd9;
|
||||
lut[13] = 8'd11;
|
||||
lut[14] = 8'd13;
|
||||
lut[15] = 8'd15;
|
||||
lut[16] = 8'd18;
|
||||
lut[17] = 8'd22;
|
||||
lut[18] = 8'd26;
|
||||
lut[19] = 8'd31;
|
||||
lut[20] = 8'd37;
|
||||
lut[21] = 8'd45;
|
||||
lut[22] = 8'd53;
|
||||
lut[23] = 8'd63;
|
||||
lut[24] = 8'd75;
|
||||
lut[25] = 8'd90;
|
||||
lut[26] = 8'd107;
|
||||
lut[27] = 8'd127;
|
||||
lut[28] = 8'd151;
|
||||
lut[29] = 8'd180;
|
||||
lut[30] = 8'd214;
|
||||
lut[31] = 8'd255;
|
||||
lut[32] = 8'd0;
|
||||
lut[33] = 8'd7;
|
||||
lut[34] = 8'd8;
|
||||
lut[35] = 8'd10;
|
||||
lut[36] = 8'd11;
|
||||
lut[37] = 8'd12;
|
||||
lut[38] = 8'd14;
|
||||
lut[39] = 8'd15;
|
||||
lut[40] = 8'd17;
|
||||
lut[41] = 8'd20;
|
||||
lut[42] = 8'd22;
|
||||
lut[43] = 8'd25;
|
||||
lut[44] = 8'd28;
|
||||
lut[45] = 8'd31;
|
||||
lut[46] = 8'd35;
|
||||
lut[47] = 8'd40;
|
||||
lut[48] = 8'd45;
|
||||
lut[49] = 8'd50;
|
||||
lut[50] = 8'd56;
|
||||
lut[51] = 8'd63;
|
||||
lut[52] = 8'd71;
|
||||
lut[53] = 8'd80;
|
||||
lut[54] = 8'd90;
|
||||
lut[55] = 8'd101;
|
||||
lut[56] = 8'd113;
|
||||
lut[57] = 8'd127;
|
||||
lut[58] = 8'd143;
|
||||
lut[59] = 8'd160;
|
||||
lut[60] = 8'd180;
|
||||
lut[61] = 8'd202;
|
||||
lut[62] = 8'd227;
|
||||
lut[63] = 8'd255;
|
||||
lut[64] = 8'd0;
|
||||
lut[65] = 8'd18;
|
||||
lut[66] = 8'd20;
|
||||
lut[67] = 8'd22;
|
||||
lut[68] = 8'd24;
|
||||
lut[69] = 8'd26;
|
||||
lut[70] = 8'd29;
|
||||
lut[71] = 8'd31;
|
||||
lut[72] = 8'd34;
|
||||
lut[73] = 8'd37;
|
||||
lut[74] = 8'd41;
|
||||
lut[75] = 8'd45;
|
||||
lut[76] = 8'd49;
|
||||
lut[77] = 8'd53;
|
||||
lut[78] = 8'd58;
|
||||
lut[79] = 8'd63;
|
||||
lut[80] = 8'd69;
|
||||
lut[81] = 8'd75;
|
||||
lut[82] = 8'd82;
|
||||
lut[83] = 8'd90;
|
||||
lut[84] = 8'd98;
|
||||
lut[85] = 8'd107;
|
||||
lut[86] = 8'd116;
|
||||
lut[87] = 8'd127;
|
||||
lut[88] = 8'd139;
|
||||
lut[89] = 8'd151;
|
||||
lut[90] = 8'd165;
|
||||
lut[91] = 8'd180;
|
||||
lut[92] = 8'd196;
|
||||
lut[93] = 8'd214;
|
||||
lut[94] = 8'd233;
|
||||
lut[95] = 8'd255;
|
||||
lut[96] = 8'd0;
|
||||
lut[97] = 8'd51;
|
||||
lut[98] = 8'd54;
|
||||
lut[99] = 8'd57;
|
||||
lut[100] = 8'd60;
|
||||
lut[101] = 8'd63;
|
||||
lut[102] = 8'd67;
|
||||
lut[103] = 8'd70;
|
||||
lut[104] = 8'd74;
|
||||
lut[105] = 8'd78;
|
||||
lut[106] = 8'd83;
|
||||
lut[107] = 8'd87;
|
||||
lut[108] = 8'd92;
|
||||
lut[109] = 8'd97;
|
||||
lut[110] = 8'd103;
|
||||
lut[111] = 8'd108;
|
||||
lut[112] = 8'd114;
|
||||
lut[113] = 8'd120;
|
||||
lut[114] = 8'd127;
|
||||
lut[115] = 8'd134;
|
||||
lut[116] = 8'd141;
|
||||
lut[117] = 8'd149;
|
||||
lut[118] = 8'd157;
|
||||
lut[119] = 8'd166;
|
||||
lut[120] = 8'd175;
|
||||
lut[121] = 8'd185;
|
||||
lut[122] = 8'd195;
|
||||
lut[123] = 8'd206;
|
||||
lut[124] = 8'd217;
|
||||
lut[125] = 8'd229;
|
||||
lut[126] = 8'd241;
|
||||
lut[127] = 8'd255;
|
||||
|
||||
end
|
||||
endmodule
|
||||
63
common/Sound/JT49/jt49_noise.v
Normal file
63
common/Sound/JT49/jt49_noise.v
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-Nov-2018
|
||||
|
||||
Based on sqmusic, by the same author
|
||||
|
||||
*/
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module jt49_noise(
|
||||
input wire cen,
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire[4:0] period,
|
||||
output reg noise
|
||||
);
|
||||
|
||||
reg[5:0] count;
|
||||
reg[16:0] poly17;
|
||||
wire poly17_zero = poly17==17'b0;
|
||||
wire noise_en;
|
||||
reg last_en;
|
||||
|
||||
wire noise_up = noise_en && !last_en;
|
||||
|
||||
always @(posedge clk ) if(cen) begin
|
||||
noise <= ~poly17[0];
|
||||
end
|
||||
|
||||
always @( posedge clk, negedge rst_n )
|
||||
if( !rst_n )
|
||||
poly17 <= 17'd0;
|
||||
else if( cen ) begin
|
||||
last_en <= noise_en;
|
||||
if( noise_up )
|
||||
poly17 <= { poly17[0] ^ poly17[3] ^ poly17_zero, poly17[16:1] };
|
||||
end
|
||||
|
||||
jt49_div #(5) u_div(
|
||||
.clk ( clk ),
|
||||
.cen ( cen ),
|
||||
.rst_n ( rst_n ),
|
||||
.period ( period ),
|
||||
.div ( noise_en )
|
||||
);
|
||||
|
||||
endmodule
|
||||
6
common/Sound/jt89/jt89.qip
Normal file
6
common/Sound/jt89/jt89.qip
Normal file
@@ -0,0 +1,6 @@
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt89.vhd ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
|
||||
159
common/Sound/jt89/jt89.v
Normal file
159
common/Sound/jt89/jt89.v
Normal file
@@ -0,0 +1,159 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: March, 8th 2017
|
||||
|
||||
This work was originally based in the implementation found on the
|
||||
SMS core of MiST. Some of the changes, all according to data sheet:
|
||||
|
||||
-Fixed volume
|
||||
-Fixed tone 2 rate option of noise generator
|
||||
-Fixed rate of noise generator
|
||||
-Fixed noise shift clear
|
||||
-Fixed noise generator update bug by which it gets updated
|
||||
multiple times if v='0'
|
||||
-Added all 0's prevention circuit to noise generator
|
||||
|
||||
*/
|
||||
|
||||
module jt89(
|
||||
input clk,
|
||||
(* direct_enable = 1 *) input clk_en,
|
||||
input rst,
|
||||
input wr_n,
|
||||
input [7:0] din,
|
||||
output signed [10:0] sound,
|
||||
output ready
|
||||
);
|
||||
|
||||
parameter interpol16=0;
|
||||
|
||||
wire signed [ 8:0] ch0, ch1, ch2, noise;
|
||||
|
||||
assign ready = 1'b1;
|
||||
(* direct_enable = 1 *) reg cen_16;
|
||||
(* direct_enable = 1 *) reg cen_4;
|
||||
|
||||
jt89_mixer #(.interpol16(interpol16)) mix(
|
||||
.clk ( clk ),
|
||||
.clk_en ( clk_en), // uses main clock enable
|
||||
.cen_16 ( cen_16),
|
||||
.cen_4 ( cen_4 ),
|
||||
.rst ( rst ),
|
||||
.ch0 ( ch0 ),
|
||||
.ch1 ( ch1 ),
|
||||
.ch2 ( ch2 ),
|
||||
.noise ( noise ),
|
||||
.sound ( sound )
|
||||
);
|
||||
|
||||
// configuration registers
|
||||
reg [9:0] tone0, tone1, tone2;
|
||||
reg [3:0] vol0, vol1, vol2, vol3;
|
||||
reg [2:0] ctrl3;
|
||||
reg [2:0] regn;
|
||||
|
||||
reg [3:0] clk_div;
|
||||
|
||||
always @(posedge clk )
|
||||
if( rst ) begin
|
||||
cen_16 <= 1'b1;
|
||||
cen_4 <= 1'b1;
|
||||
end else begin
|
||||
cen_16 <= clk_en & (&clk_div);
|
||||
cen_4 <= clk_en & (&clk_div[1:0]);
|
||||
end
|
||||
|
||||
always @(posedge clk )
|
||||
if( rst )
|
||||
clk_div <= 4'd0;
|
||||
else if( clk_en )
|
||||
clk_div <= clk_div + 1'b1;
|
||||
|
||||
reg clr_noise, last_wr;
|
||||
wire [2:0] reg_sel = din[7] ? din[6:4] : regn;
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst ) begin
|
||||
{ vol0, vol1, vol2, vol3 } <= {16{1'b1}};
|
||||
{ tone0, tone1, tone2 } <= 30'd0;
|
||||
ctrl3 <= 3'b100;
|
||||
end
|
||||
else begin
|
||||
last_wr <= wr_n;
|
||||
if( !wr_n && last_wr ) begin
|
||||
clr_noise <= din[7:4] == 4'b1110; // clear noise
|
||||
// when there is an access to the control register
|
||||
regn <= reg_sel;
|
||||
case( reg_sel )
|
||||
3'b00_0: if( din[7] ) tone0[3:0]<=din[3:0]; else tone0[9:4]<=din[5:0];
|
||||
3'b01_0: if( din[7] ) tone1[3:0]<=din[3:0]; else tone1[9:4]<=din[5:0];
|
||||
3'b10_0: if( din[7] ) tone2[3:0]<=din[3:0]; else tone2[9:4]<=din[5:0];
|
||||
3'b11_0: ctrl3 <= din[2:0];
|
||||
3'b00_1: vol0 <= din[3:0];
|
||||
3'b01_1: vol1 <= din[3:0];
|
||||
3'b10_1: vol2 <= din[3:0];
|
||||
3'b11_1: vol3 <= din[3:0];
|
||||
endcase
|
||||
end
|
||||
else clr_noise <= 1'b0;
|
||||
end
|
||||
|
||||
jt89_tone u_tone0(
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.clk_en ( cen_16 ),
|
||||
.vol ( vol0 ),
|
||||
.tone ( tone0 ),
|
||||
.snd ( ch0 ),
|
||||
.out ( )
|
||||
);
|
||||
|
||||
jt89_tone u_tone1(
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.clk_en ( cen_16 ),
|
||||
.vol ( vol1 ),
|
||||
.tone ( tone1 ),
|
||||
.snd ( ch1 ),
|
||||
.out ( )
|
||||
);
|
||||
|
||||
wire out2;
|
||||
|
||||
jt89_tone u_tone2(
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.clk_en ( cen_16 ),
|
||||
.vol ( vol2 ),
|
||||
.tone ( tone2 ),
|
||||
.snd ( ch2 ),
|
||||
.out ( out2 )
|
||||
);
|
||||
|
||||
jt89_noise u_noise(
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.clk_en ( cen_16 ),
|
||||
.clr ( clr_noise ),
|
||||
.vol ( vol3 ),
|
||||
.ctrl3 ( ctrl3 ),
|
||||
.tone2 ( tone2 ),
|
||||
.snd ( noise )
|
||||
);
|
||||
|
||||
endmodule
|
||||
19
common/Sound/jt89/jt89.vhd
Normal file
19
common/Sound/jt89/jt89.vhd
Normal file
@@ -0,0 +1,19 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package jt89 is
|
||||
|
||||
component jt89
|
||||
port
|
||||
(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic; -- CPU clock
|
||||
clk_en : in std_logic := '1'; -- optional clock enable, if not needed leave as '1'
|
||||
din : in std_logic_vector(7 downto 0);
|
||||
wr_n : in std_logic;
|
||||
ready : out std_logic;
|
||||
sound : out std_logic_vector(10 downto 0) -- signed
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
68
common/Sound/jt89/jt89_mixer.v
Normal file
68
common/Sound/jt89/jt89_mixer.v
Normal file
@@ -0,0 +1,68 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: December, 1st 2018
|
||||
|
||||
*/
|
||||
|
||||
module jt89_mixer #(parameter bw=9, interpol16=0)(
|
||||
input rst,
|
||||
input clk,
|
||||
input clk_en,
|
||||
input cen_16,
|
||||
input cen_4,
|
||||
input [bw-1:0] ch0,
|
||||
input [bw-1:0] ch1,
|
||||
input [bw-1:0] ch2,
|
||||
input [bw-1:0] noise,
|
||||
output signed [bw+1:0] sound
|
||||
);
|
||||
|
||||
reg signed [bw+1:0] fresh;
|
||||
|
||||
always @(posedge clk)
|
||||
fresh <=
|
||||
{ {2{ch0[bw-1]}}, ch0 }+
|
||||
{ {2{ch1[bw-1]}}, ch1 }+
|
||||
{ {2{ch2[bw-1]}}, ch2 }+
|
||||
{ {2{noise[bw-1]}}, noise };
|
||||
|
||||
generate
|
||||
if( interpol16==1 ) begin
|
||||
wire signed [bw+1:0] snd4;
|
||||
localparam calcw=bw+8;
|
||||
jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate1 (
|
||||
.rst ( rst ),
|
||||
.clk ( clk ),
|
||||
.cen_in ( cen_16 ),
|
||||
.cen_out( cen_4 ),
|
||||
.snd_in ( fresh ),
|
||||
.snd_out( snd4 )
|
||||
);
|
||||
jt12_interpol #(.calcw(calcw),.inw(bw+2),.rate(4),.m(4),.n(2)) u_uprate2 (
|
||||
.rst ( rst ),
|
||||
.clk ( clk ),
|
||||
.cen_in ( cen_4 ),
|
||||
.cen_out( clk_en ),
|
||||
.snd_in ( snd4 ),
|
||||
.snd_out( sound )
|
||||
);
|
||||
end else
|
||||
assign sound = fresh;
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
76
common/Sound/jt89/jt89_noise.v
Normal file
76
common/Sound/jt89/jt89_noise.v
Normal file
@@ -0,0 +1,76 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: March, 8th 2017
|
||||
|
||||
This work was originally based in the implementation found on the
|
||||
SMS core of MiST
|
||||
|
||||
*/
|
||||
|
||||
module jt89_noise(
|
||||
input clk,
|
||||
(* direct_enable = 1 *) input clk_en,
|
||||
input rst,
|
||||
input clr,
|
||||
input [2:0] ctrl3,
|
||||
input [3:0] vol,
|
||||
input [9:0] tone2,
|
||||
output [8:0] snd
|
||||
);
|
||||
|
||||
reg [15:0] shift;
|
||||
reg [10:0] cnt;
|
||||
reg update;
|
||||
|
||||
jt89_vol u_vol(
|
||||
.rst ( rst ),
|
||||
.clk ( clk ),
|
||||
.clk_en ( clk_en ),
|
||||
.din ( shift[0] ),
|
||||
.vol ( vol ),
|
||||
.snd ( snd )
|
||||
);
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst ) begin
|
||||
cnt <= 'd0;
|
||||
end else if( clk_en ) begin
|
||||
if( cnt==11'd1 ) begin
|
||||
case( ctrl3[1:0] )
|
||||
2'd0: cnt <= 11'h20; // clk_en already divides by 16
|
||||
2'd1: cnt <= 11'h40;
|
||||
2'd2: cnt <= 11'h80;
|
||||
2'd3: cnt <= (tone2 == 0) ? 11'h02 : {tone2, 1'b0};
|
||||
endcase
|
||||
end else begin
|
||||
cnt <= cnt-11'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire fb = ctrl3[2]?(shift[0]^shift[3]):shift[0];
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst || clr )
|
||||
shift <= { 1'b1, 15'd0 };
|
||||
else if( clk_en ) begin
|
||||
if( cnt==1 ) begin
|
||||
shift <= (|shift == 1'b0) ? {1'b1, 15'd0 } : {fb, shift[15:1]};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
10
common/Sound/jt89/jt89_sms.qip
Normal file
10
common/Sound/jt89/jt89_sms.qip
Normal file
@@ -0,0 +1,10 @@
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt89_sms.vhd ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_sms.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_interpol.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_comb.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_dac2.v ]
|
||||
43
common/Sound/jt89/jt89_sms.v
Normal file
43
common/Sound/jt89/jt89_sms.v
Normal file
@@ -0,0 +1,43 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: Dec, 22nd, 2018
|
||||
|
||||
JT89 with x16 interpolation filter. For use with SEGA MASTER SYSTEM cores.
|
||||
|
||||
*/
|
||||
|
||||
module jt89_sms(
|
||||
input clk,
|
||||
input rst,
|
||||
input wr_n,
|
||||
input [7:0] din,
|
||||
output signed [10:0] sound,
|
||||
output ready
|
||||
);
|
||||
|
||||
jt89 #(.interpol16(1)) u_jt89(
|
||||
.clk ( clk ),
|
||||
.clk_en ( 1'b1 ),
|
||||
.rst ( rst ),
|
||||
.wr_n ( wr_n ),
|
||||
.din ( din ),
|
||||
.sound ( sound ), // output interpolated at clk data rate
|
||||
.ready ( ready )
|
||||
);
|
||||
|
||||
endmodule // jt89_sms
|
||||
29
common/Sound/jt89/jt89_sms.vhd
Normal file
29
common/Sound/jt89/jt89_sms.vhd
Normal file
@@ -0,0 +1,29 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
package jt89 is
|
||||
|
||||
-- SMS wrapper. clk_en assumed to be 1. x16 LPF+interpolator enabled
|
||||
component jt89_sms
|
||||
port
|
||||
(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic; -- CPU clock
|
||||
din : in std_logic_vector(7 downto 0);
|
||||
wr_n : in std_logic;
|
||||
ready : out std_logic;
|
||||
sound : out std_logic_vector(10 downto 0) -- signed
|
||||
);
|
||||
end component;
|
||||
|
||||
component jt12_dac2
|
||||
port
|
||||
(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic; -- CPU clock
|
||||
din : in std_logic_vector(10 downto 0); -- signed
|
||||
dout : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
end;
|
||||
63
common/Sound/jt89/jt89_tone.v
Normal file
63
common/Sound/jt89/jt89_tone.v
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: March, 8th 2017
|
||||
|
||||
This work was originally based in the implementation found on the
|
||||
SMS core of MiST
|
||||
|
||||
*/
|
||||
|
||||
module jt89_tone(
|
||||
input clk,
|
||||
(* direct_enable = 1 *) input clk_en,
|
||||
input rst,
|
||||
input [9:0] tone,
|
||||
input [3:0] vol,
|
||||
output [8:0] snd,
|
||||
output reg out
|
||||
);
|
||||
|
||||
reg [9:0] cnt;
|
||||
reg last_out;
|
||||
|
||||
jt89_vol u_vol(
|
||||
.rst ( rst ),
|
||||
.clk ( clk ),
|
||||
.clk_en ( clk_en ),
|
||||
.din ( out ),
|
||||
.vol ( vol ),
|
||||
.snd ( snd )
|
||||
);
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst ) begin
|
||||
cnt <= 10'd0;
|
||||
out <= 1'b0;
|
||||
end else if( clk_en ) begin
|
||||
if( tone==10'd0 || tone==10'd1 ) // special case. This is used for sample playing.
|
||||
out <= 1'b1;
|
||||
else begin
|
||||
if( cnt[9:0]==10'd1 ) begin
|
||||
cnt[9:0] <= (tone==10'd0) ? 10'd1 : tone;
|
||||
out <= ~out;
|
||||
end
|
||||
else cnt <= cnt-10'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
5
common/Sound/jt89/jt89_verilog.qip
Normal file
5
common/Sound/jt89/jt89_verilog.qip
Normal file
@@ -0,0 +1,5 @@
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_noise.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_vol.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_mixer.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt89_tone.v ]
|
||||
63
common/Sound/jt89/jt89_vol.v
Normal file
63
common/Sound/jt89/jt89_vol.v
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This file is part of JT89.
|
||||
|
||||
JT89 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT89 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 JT89. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: December, 1st 2018
|
||||
|
||||
This work was originally based in the implementation found on the
|
||||
SMS core of MiST
|
||||
|
||||
*/
|
||||
|
||||
module jt89_vol(
|
||||
input clk,
|
||||
input clk_en,
|
||||
input rst,
|
||||
input din,
|
||||
input [3:0] vol,
|
||||
output reg signed [8:0] snd
|
||||
);
|
||||
|
||||
|
||||
reg [7:0] max;
|
||||
|
||||
always @(*)
|
||||
case ( vol ) // 2dB per LSB (20*log10)
|
||||
4'd0: max = 8'd255;
|
||||
4'd1: max = 8'd203;
|
||||
4'd2: max = 8'd161;
|
||||
4'd3: max = 8'd128;
|
||||
4'd4: max = 8'd102;
|
||||
4'd5: max = 8'd81;
|
||||
4'd6: max = 8'd64;
|
||||
4'd7: max = 8'd51;
|
||||
4'd8: max = 8'd40;
|
||||
4'd9: max = 8'd32;
|
||||
4'd10: max = 8'd26;
|
||||
4'd11: max = 8'd20;
|
||||
4'd12: max = 8'd16;
|
||||
4'd13: max = 8'd13;
|
||||
4'd14: max = 8'd10;
|
||||
4'd15: max = 8'd0;
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst )
|
||||
snd <= 9'd0;
|
||||
else if( clk_en )
|
||||
snd <= din ? {1'b0,max} : -{1'b0,max};
|
||||
|
||||
endmodule
|
||||
59
common/Sound/jt89/mixer/jt12_comb.v
Normal file
59
common/Sound/jt89/mixer/jt12_comb.v
Normal file
@@ -0,0 +1,59 @@
|
||||
/* This file is part of JT12.
|
||||
|
||||
|
||||
JT12 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT12 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 JT12. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-12-2018
|
||||
|
||||
*/
|
||||
|
||||
module jt12_comb #(parameter
|
||||
w=16, // bit width
|
||||
m=1 // depth of comb filter
|
||||
)(
|
||||
input rst,
|
||||
input clk,
|
||||
(* direct_enable *) input cen,
|
||||
input signed [w-1:0] snd_in,
|
||||
output reg signed [w-1:0] snd_out
|
||||
);
|
||||
|
||||
wire signed [w-1:0] prev;
|
||||
|
||||
// m-delay stage
|
||||
generate
|
||||
genvar k;
|
||||
reg signed [w-1:0] mem[0:m-1];
|
||||
assign prev=mem[m-1];
|
||||
for(k=0;k<m;k=k+1) begin : mem_gen
|
||||
always @(posedge clk)
|
||||
if(rst) begin
|
||||
mem[k] <= {w{1'b0}};
|
||||
end else if(cen) begin
|
||||
mem[k] <= k==0 ? snd_in : mem[k-1];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Comb filter at synthesizer sampling rate
|
||||
always @(posedge clk)
|
||||
if(rst) begin
|
||||
snd_out <= {w{1'b0}};
|
||||
end else if(cen) begin
|
||||
snd_out <= snd_in - prev;
|
||||
end
|
||||
|
||||
endmodule // jt12_comb
|
||||
63
common/Sound/jt89/mixer/jt12_dac2.v
Normal file
63
common/Sound/jt89/mixer/jt12_dac2.v
Normal file
@@ -0,0 +1,63 @@
|
||||
/* This file is part of JT12.
|
||||
|
||||
JT12 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT12 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 JT12. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: March, 9th 2017
|
||||
*/
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
|
||||
input sampling rate must be the same as clk frequency
|
||||
interpolate input signal accordingly to get the
|
||||
right sampling rate.
|
||||
|
||||
Refer to sigmadelta.ods to see how the internal width (int_w)
|
||||
was determined.
|
||||
|
||||
*/
|
||||
|
||||
module jt12_dac2 #(parameter width=11)
|
||||
(
|
||||
input clk,
|
||||
input rst,
|
||||
input signed [width-1:0] din,
|
||||
output reg dout
|
||||
);
|
||||
|
||||
localparam int_w = width+5;
|
||||
|
||||
reg [int_w-1:0] y, error, error_1, error_2;
|
||||
|
||||
wire [width-1:0] undin = { ~din[width-1], din[width-2:0] };
|
||||
|
||||
always @(*) begin
|
||||
y = undin + { error_1, 1'b0} - error_2;
|
||||
dout = ~y[int_w-1];
|
||||
error = y - {dout, {width{1'b0}}};
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst ) begin
|
||||
error_1 <= {int_w{1'b0}};
|
||||
error_2 <= {int_w{1'b0}};
|
||||
end else begin
|
||||
error_1 <= error;
|
||||
error_2 <= error_1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
92
common/Sound/jt89/mixer/jt12_interpol.v
Normal file
92
common/Sound/jt89/mixer/jt12_interpol.v
Normal file
@@ -0,0 +1,92 @@
|
||||
/* This file is part of JT12.
|
||||
|
||||
|
||||
JT12 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
JT12 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 JT12. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 10-12-2018
|
||||
|
||||
*/
|
||||
|
||||
module jt12_interpol #(parameter calcw=18, inw=16,
|
||||
n=2, // number of stages
|
||||
m=1, // depth of comb filter
|
||||
rate=2 // it will stuff with as many as (rate-1) zeros
|
||||
)(
|
||||
input rst,
|
||||
input clk,
|
||||
(* direct_enable *) input cen_in,
|
||||
(* direct_enable *) input cen_out,
|
||||
input signed [inw-1:0] snd_in,
|
||||
output reg signed [inw-1:0] snd_out
|
||||
);
|
||||
|
||||
reg signed [calcw-1:0] inter6;
|
||||
wire signed [calcw-1:0] comb_op, integ_op;
|
||||
localparam wdiff = calcw - inw;
|
||||
|
||||
generate
|
||||
genvar k;
|
||||
wire [calcw-1:0] comb_data[0:n];
|
||||
assign comb_data[0] = { {wdiff{snd_in[inw-1]}}, snd_in };
|
||||
assign comb_op = comb_data[n];
|
||||
for(k=0;k<n;k=k+1) begin : comb_gen
|
||||
jt12_comb #(.w(calcw),.m(m)) u_comb(
|
||||
.rst ( rst ),
|
||||
.clk ( clk ),
|
||||
.cen ( cen_in ),
|
||||
.snd_in ( comb_data[k] ),
|
||||
.snd_out( comb_data[k+1] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
reg [rate-1:0] inter_cnt;
|
||||
|
||||
// interpolator
|
||||
always @(posedge clk)
|
||||
if(rst) begin
|
||||
inter6 <= {calcw{1'b0}};
|
||||
inter_cnt <= { {(rate-1){1'b0}}, 1'b1};
|
||||
end else if(cen_out) begin
|
||||
inter6 <= inter_cnt[0] ? comb_op : {calcw{1'b0}};
|
||||
inter_cnt <= { inter_cnt[0], inter_cnt[rate-1:1] };
|
||||
end
|
||||
|
||||
// integrator at clk x cen sampling rate
|
||||
generate
|
||||
genvar k2;
|
||||
reg [calcw-1:0] integ_data[0:n];
|
||||
assign integ_op = integ_data[n];
|
||||
always @(*)
|
||||
integ_data[0] = inter6;
|
||||
for(k2=1;k2<=n;k2=k2+1) begin : integ_gen
|
||||
always @(posedge clk)
|
||||
if(rst) begin
|
||||
integ_data[k2] <= {calcw{1'b0}};
|
||||
end else if(cen_out) begin
|
||||
integ_data[k2] <= integ_data[k2] + integ_data[k2-1];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk)
|
||||
if(rst) begin
|
||||
snd_out <= {inw{1'b0}};
|
||||
end else if(cen_out) begin
|
||||
snd_out<= integ_op[calcw-1:wdiff];
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user