From 5fc4ce7cfb2c7477d8cf97ed679733c1f20e05af Mon Sep 17 00:00:00 2001 From: Cray Elliott Date: Fri, 23 Aug 2024 03:44:43 -0700 Subject: [PATCH 1/2] Update jt12 to latest version from upstream update jt49 to upstream version --- files.qip | 6 +- rtl/jt12/README.md | 51 ++++- rtl/jt12/hdl/adpcm/jt10_adpcm_cnt.v | 3 +- rtl/jt12/hdl/adpcm/jt10_adpcm_div.v | 30 +-- rtl/jt12/hdl/adpcm/jt10_adpcm_drvA.v | 2 - rtl/jt12/hdl/adpcm/jt10_adpcm_gain.v | 14 +- rtl/jt12/hdl/adpcm/jt10_adpcmb_interpol.v | 2 +- rtl/jt12/hdl/jt03.v | 61 ++++-- rtl/jt12/hdl/jt03.yaml | 36 +++ rtl/jt12/hdl/jt03_acc.v | 25 ++- rtl/jt12/hdl/jt10.v | 40 ++-- rtl/jt12/hdl/jt10.yaml | 36 +++ rtl/jt12/hdl/jt10_acc.v | 2 +- rtl/jt12/hdl/jt12.v | 29 ++- rtl/jt12/hdl/jt12.yaml | 10 + rtl/jt12/hdl/jt12_acc.v | 4 +- rtl/jt12/hdl/jt12_div.v | 32 +-- rtl/jt12/hdl/jt12_eg_cnt.v | 2 +- rtl/jt12/hdl/jt12_eg_ctrl.v | 16 +- rtl/jt12/hdl/jt12_exprom.v | 1 - rtl/jt12/hdl/jt12_kon.v | 35 ++- rtl/jt12/hdl/jt12_lfo.v | 1 - rtl/jt12/hdl/jt12_mmr.v | 196 +++++++++-------- rtl/jt12/hdl/jt12_mod.v | 1 - rtl/jt12/hdl/jt12_op.v | 60 ++++- rtl/jt12/hdl/jt12_pcm.v | 4 +- rtl/jt12/hdl/jt12_pcm_interpol.v | 30 +-- rtl/jt12/hdl/jt12_pg.v | 1 - rtl/jt12/hdl/jt12_pg_sum.v | 62 +++--- rtl/jt12/hdl/jt12_pm.v | 2 - rtl/jt12/hdl/jt12_reg.v | 81 ++----- rtl/jt12/hdl/jt12_reg_ch.v | 128 +++++++++++ rtl/jt12/hdl/jt12_sh.v | 1 - rtl/jt12/hdl/jt12_sh24.v | 1 - rtl/jt12/hdl/jt12_sh_rst.v | 19 +- rtl/jt12/hdl/jt12_single_acc.v | 1 - rtl/jt12/hdl/jt12_sumch.v | 1 - rtl/jt12/hdl/jt12_timers.v | 217 +++++++++++-------- rtl/jt12/hdl/jt12_top.v | 99 ++++++--- rtl/jt12/hdl/mixer/jt12_fm_uprate.v | 15 +- rtl/jt12/hdl/mixer/jt12_genmix.v | 4 +- rtl/jt12/hdl/mixer/jt12_mixer.v | 2 +- rtl/jt12/{hdl => target/quartus}/jt03.qip | 76 +++---- rtl/jt12/{hdl => target/quartus}/jt03_fm.qip | 66 +++--- rtl/jt12/{hdl => target/quartus}/jt10.qip | 111 +++++----- rtl/jt12/{hdl => target/quartus}/jt12.qip | 84 +++---- rtl/jt49/README.md | 69 +++++- rtl/jt49/hdl/filter/jt49_dcrm.v | 2 +- rtl/jt49/hdl/filter/jt49_dcrm2.v | 22 +- rtl/jt49/hdl/filter/jt49_dly.v | 8 +- rtl/jt49/hdl/filter/jt49_mave.v | 24 +- rtl/jt49/hdl/jt49.v | 39 +++- rtl/jt49/hdl/jt49.yaml | 8 + rtl/jt49/hdl/jt49_bus.v | 22 +- rtl/jt49/hdl/jt49_exp.v | 40 +++- rtl/jt49/hdl/jt49_noise.v | 1 - rtl/jt49/{hdl => syn/quartus}/jt49.qip | 14 +- 57 files changed, 1224 insertions(+), 725 deletions(-) create mode 100644 rtl/jt12/hdl/jt03.yaml create mode 100644 rtl/jt12/hdl/jt10.yaml create mode 100644 rtl/jt12/hdl/jt12.yaml create mode 100644 rtl/jt12/hdl/jt12_reg_ch.v rename rtl/jt12/{hdl => target/quartus}/jt03.qip (57%) rename rtl/jt12/{hdl => target/quartus}/jt03_fm.qip (65%) rename rtl/jt12/{hdl => target/quartus}/jt10.qip (62%) rename rtl/jt12/{hdl => target/quartus}/jt12.qip (64%) create mode 100644 rtl/jt49/hdl/jt49.yaml rename rtl/jt49/{hdl => syn/quartus}/jt49.qip (66%) diff --git a/files.qip b/files.qip index cc72e11..c1928b6 100644 --- a/files.qip +++ b/files.qip @@ -1,5 +1,5 @@ -set_global_assignment -name QIP_FILE rtl/jt12/hdl/jt10.qip -set_global_assignment -name QIP_FILE rtl/jt49/hdl/jt49.qip +set_global_assignment -name QIP_FILE rtl/jt12/target/quartus/jt10.qip +set_global_assignment -name QIP_FILE rtl/jt49/syn/quartus/jt49.qip set_global_assignment -name QIP_FILE rtl/video/video.qip set_global_assignment -name QIP_FILE rtl/cd/cd.qip set_global_assignment -name QIP_FILE rtl/io/io.qip @@ -11,4 +11,4 @@ set_global_assignment -name QIP_FILE rtl/cpu/T80/T80.qip set_global_assignment -name VERILOG_FILE rtl/cpu/cpu_z80.v set_global_assignment -name VERILOG_FILE rtl/cpu/cpu_68k.v set_global_assignment -name SYSTEMVERILOG_FILE neogeo.sv -set_global_assignment -name SDC_FILE neogeo.sdc +set_global_assignment -name SDC_FILE NeoGeo.sdc diff --git a/rtl/jt12/README.md b/rtl/jt12/README.md index 6922b09..80f1c7a 100644 --- a/rtl/jt12/README.md +++ b/rtl/jt12/README.md @@ -2,7 +2,7 @@ =================================================================== You can show your appreciation through -* [Patreon](https://patreon.com/topapate), by supporting releases +* [Patreon](https://patreon.com/jotego), by supporting releases * [Paypal](https://paypal.me/topapate), with a donation @@ -10,19 +10,50 @@ JT12 is an FM sound source written in Verilog, fully compatible with YM2612/YM34 The implementation tries to be as close to original hardware as possible. Low usage of FPGA resources has also been a design goal. Except in the operator section (jt12_op) where an exact replica of the original circuit is done. This could be done in less space with a different style but because this piece of the circuit was reversed engineered by Sauraen, I decided to use that knowledge. -Directories: +## Using JT12 in a git project -hdl -> all relevant RTL files, written in verilog -ver -> test benches -ver/verilator -> test bench that can play vgm files +If you are using JT12 in a git project, the best way to add it to your project is: -Usage: +1. Optionally fork JT12's repository to your own GitHub account +2. Add it as a submodule to your git project: `git submodule add https://github.com/jotego/jt12.git` +3. Now you can refer to the RTL files in **jt12/hdl** -YM2610: top level file hdl/jt10.v. Use jt10.qip to automatically get all relevant files in Quartus. -YM2612: top level file hdl/jt12.v. Use jt12.qip to automatically get all relevant files in Quartus. -YM2203: top level file hdl/jt03.v. Use jt03.qip to automatically get all relevant files in Quartus. +The advantages of a using a git submodule are: + +1. Your project contains a reference to a commit of the JT12 repository +2. As long as you do not manually update the JT12 submodule, it will keep pointing to the same commit +3. Each time you make a commit in your project, it will include a pointer to the JT12 commit used. So you will always know the JT12 that worked for you +4. If JT12 is updated and you want to get the changes, simply update the submodule using git. The new JT12 commit used will be annotated in your project's next commit. So the history of your project will reflect that change too. +5. JT12 files will be intact and you will use the files without altering them. + +## Directories + +* hdl -> all relevant RTL files, written in verilog +* ver -> test benches +* ver/verilator -> test bench that can play vgm files + +## Usage + +Chip | Top Level | QIP File +--------|---------------|--------- +YM2610 | jt10.v | jt10.qip +YM2612 | jt12.v | jt12.qip +YM2203 | jt03.v | jt03.qip ## Simulation -============= There are several simulation test benches in the **ver** folder. The most important one is in the **ver/verilator** folder. The simulation script is called with the shell script **go** in the same folder. The script will compile the file **test.cpp** together with other files and the design and will simulate the tune specificied with the -f command. It can read **vgm** tunes and generate .wav output of them. + +## Related Projects + +Other sound chips from the same author + +Chip | Repository +-----------------------|------------ +YM2203, YM2612, YM2610 | [JT12](https://github.com/jotego/jt12) +YM2151 | [JT51](https://github.com/jotego/jt51) +YM3526 | [JTOPL](https://github.com/jotego/jtopl) +YM2149 | [JT49](https://github.com/jotego/jt49) +sn76489an | [JT89](https://github.com/jotego/jt89) +OKI 6295 | [JT6295](https://github.com/jotego/jt6295) +OKI MSM5205 | [JT5205](https://github.com/jotego/jt5205) \ No newline at end of file diff --git a/rtl/jt12/hdl/adpcm/jt10_adpcm_cnt.v b/rtl/jt12/hdl/adpcm/jt10_adpcm_cnt.v index 7942e94..3e1cec0 100644 --- a/rtl/jt12/hdl/adpcm/jt10_adpcm_cnt.v +++ b/rtl/jt12/hdl/adpcm/jt10_adpcm_cnt.v @@ -124,7 +124,8 @@ always @(posedge clk or negedge rst_n) if( !rst_n ) begin addr1 <= 'd0; addr2 <= 'd0; addr3 <= 'd0; addr4 <= 'd0; addr5 <= 'd0; addr6 <= 'd0; - done1 <= 'd1; done5 <= 'd1; done6 <= 'd1; + done1 <= 'd1; done2 <= 'd1; done3 <= 'd1; + done4 <= 'd1; done5 <= 'd1; done6 <= 'd1; start1 <= 'd0; start2 <= 'd0; start3 <= 'd0; start4 <= 'd0; start5 <= 'd0; start6 <= 'd0; end1 <= 'd0; end2 <= 'd0; end3 <= 'd0; diff --git a/rtl/jt12/hdl/adpcm/jt10_adpcm_div.v b/rtl/jt12/hdl/adpcm/jt10_adpcm_div.v index ef9c541..e669874 100644 --- a/rtl/jt12/hdl/adpcm/jt10_adpcm_div.v +++ b/rtl/jt12/hdl/adpcm/jt10_adpcm_div.v @@ -22,39 +22,39 @@ // calculates d=a/b // a = b*d + r -module jt10_adpcm_div #(parameter dw=16)( +module jt10_adpcm_div #(parameter DW=16)( input rst_n, input clk, // CPU clock input cen, input start, // strobe - input [dw-1:0] a, - input [dw-1:0] b, - output reg [dw-1:0] d, - output reg [dw-1:0] r, + input [DW-1:0] a, + input [DW-1:0] b, + output reg [DW-1:0] d, + output reg [DW-1:0] r, output working ); -reg [dw-1:0] cycle; +reg [DW-1:0] cycle; assign working = cycle[0]; -wire [dw:0] sub = { r[dw-2:0], d[dw-1] } - b; +wire [DW:0] sub = { r[DW-2:0], d[DW-1] } - b; always @(posedge clk or negedge rst_n) if( !rst_n ) begin cycle <= 'd0; end else if(cen) begin if( start ) begin - cycle <= ~16'd0; - r <= 16'd0; + cycle <= {DW{1'b1}}; + r <= 0; d <= a; end else if(cycle[0]) begin - cycle <= { 1'b0, cycle[dw-1:1] }; - if( sub[dw] == 0 ) begin - r <= sub[dw-1:0]; - d <= { d[dw-2:0], 1'b1}; + cycle <= { 1'b0, cycle[DW-1:1] }; + if( sub[DW] == 0 ) begin + r <= sub[DW-1:0]; + d <= { d[DW-2:0], 1'b1}; end else begin - r <= { r[dw-2:0], d[dw-1] }; - d <= { d[dw-2:0], 1'b0 }; + r <= { r[DW-2:0], d[DW-1] }; + d <= { d[DW-2:0], 1'b0 }; end end end diff --git a/rtl/jt12/hdl/adpcm/jt10_adpcm_drvA.v b/rtl/jt12/hdl/adpcm/jt10_adpcm_drvA.v index 3f08511..e98ea7c 100644 --- a/rtl/jt12/hdl/adpcm/jt10_adpcm_drvA.v +++ b/rtl/jt12/hdl/adpcm/jt10_adpcm_drvA.v @@ -54,8 +54,6 @@ module jt10_adpcm_drvA( input [5:0] ch_enable ); -/* verilator tracing_on */ - reg [5:0] cur_ch; reg [5:0] en_ch; reg [3:0] data; diff --git a/rtl/jt12/hdl/adpcm/jt10_adpcm_gain.v b/rtl/jt12/hdl/adpcm/jt10_adpcm_gain.v index 3bad62a..48f2985 100644 --- a/rtl/jt12/hdl/adpcm/jt10_adpcm_gain.v +++ b/rtl/jt12/hdl/adpcm/jt10_adpcm_gain.v @@ -38,7 +38,12 @@ module jt10_adpcm_gain( output signed [15:0] pcm_att ); +reg [9:0] lin_5b, lin1, lin2, lin6; +reg [7:0] lracl1, lracl2, lracl3, lracl4, lracl5, lracl6; +reg [6:0] db5; reg [5:0] up_ch_dec; +reg [3:0] sh1, sh6; + always @(*) case(up_ch) 3'd0: up_ch_dec = 6'b000_001; @@ -52,7 +57,6 @@ always @(*) //wire [5:0] en_ch2 = { en_ch[4:0], en_ch[5] }; // shift the bits to fit in the pipeline slot correctly -reg [6:0] db5; always @(*) case( db5[2:0] ) 3'd0: lin_5b = 10'd512; @@ -65,9 +69,6 @@ always @(*) 3'd7: lin_5b = 10'd280; endcase -reg [7:0] lracl1, lracl2, lracl3, lracl4, lracl5, lracl6; -reg [9:0] lin_5b, lin1, lin2, lin6; -reg [3:0] sh1, sh6; // dB to linear conversion assign lr = lracl1[7:6]; @@ -114,6 +115,8 @@ reg [3:0] shcnt1, shcnt2, shcnt3, shcnt4, shcnt5, shcnt6; reg shcnt_mod3, shcnt_mod4, shcnt_mod5; reg [31:0] pcm2_mul; wire signed [15:0] lin2s = {6'b0,lin2}; +reg signed [15:0] pcm1, pcm2, pcm3, pcm4, pcm5, pcm6; +reg match2; always @(*) begin shcnt_mod3 = shcnt3 != 0; @@ -122,9 +125,6 @@ always @(*) begin pcm2_mul = pcm2 * lin2s; end -reg signed [15:0] pcm1, pcm2, pcm3, pcm4, pcm5, pcm6; -reg match2; - assign pcm_att = pcm1; always @(posedge clk or negedge rst_n) diff --git a/rtl/jt12/hdl/adpcm/jt10_adpcmb_interpol.v b/rtl/jt12/hdl/adpcm/jt10_adpcmb_interpol.v index 8c0284c..4a9a04a 100644 --- a/rtl/jt12/hdl/adpcm/jt10_adpcmb_interpol.v +++ b/rtl/jt12/hdl/adpcm/jt10_adpcmb_interpol.v @@ -80,7 +80,7 @@ always @(posedge clk) if(cen55) begin else pcminter <= ( (pcminter < pcmlast) == step_sign ) ? pcminter : step_sign ? pcminter - step : pcminter + step; end -jt10_adpcm_div #(.dw(16)) u_div( +jt10_adpcm_div #(.DW(16)) u_div( .rst_n ( rst_n ), .clk ( clk ), .cen ( cen ), diff --git a/rtl/jt12/hdl/jt03.v b/rtl/jt12/hdl/jt03.v index cf12eaa..8092c9e 100644 --- a/rtl/jt12/hdl/jt03.v +++ b/rtl/jt12/hdl/jt03.v @@ -1,6 +1,6 @@ /* 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 @@ -21,8 +21,6 @@ // Wrapper to output only combined channels. Defaults to YM2203 mode. - - module jt03( input rst, // rst should be at least 6 clk&cen cycles long input clk, // CPU clock @@ -31,22 +29,35 @@ module jt03( input addr, input cs_n, input wr_n, - + output [7:0] dout, output irq_n, + // I/O pins used by YM2203 embedded YM2149 chip + input [7:0] IOA_in, + input [7:0] IOB_in, + output [7:0] IOA_out, + output [7:0] IOB_out, + output IOA_oe, + output IOB_oe, // Separated output output [ 7:0] psg_A, output [ 7:0] psg_B, output [ 7:0] psg_C, output signed [15:0] fm_snd, // combined output - output [ 9:0] psg_snd, + output [ 9:0] psg_snd, output signed [15:0] snd, - output snd_sample + output snd_sample, + // Debug + //input [ 7:0] debug_bus, + output [ 7:0] debug_view ); +parameter YM2203_LUMPED=0; // set to 1 if all PSG outputs are shorted together without any resistor + jt12_top #( - .use_lfo(0),.use_ssg(1), .num_ch(3), .use_pcm(0), .use_adpcm(0) ) + .use_lfo(0),.use_ssg(1), .num_ch(3), .use_pcm(0), .use_adpcm(0), .mask_div(0), + .YM2203_LUMPED(YM2203_LUMPED) ) u_jt12( .rst ( rst ), // rst should be at least 6 clk&cen cycles long .clk ( clk ), // CPU clock @@ -55,23 +66,31 @@ u_jt12( .addr ( {1'b0, addr} ), .cs_n ( cs_n ), .wr_n ( wr_n ), - + .ch_enable ( 6'd0 ), + .dout ( dout ), .irq_n ( irq_n ), + // YM2203 I/O pins + .IOA_in ( IOA_in ), + .IOB_in ( IOB_in ), + .IOA_out ( IOA_out ), + .IOB_out ( IOB_out ), + .IOA_oe ( IOA_oe ), + .IOB_oe ( IOB_oe ), // Unused ADPCM pins - .en_hifi_pcm ( 1'b0 ), // used only on YM2612 mode - .adpcma_addr ( ), // real hardware has 10 pins multiplexed through RMPX pin - .adpcma_bank ( ), - .adpcma_roe_n ( ), // ADPCM-A ROM output enable - .adpcma_data ( 8'd0 ), // Data from RAM - .adpcmb_data ( 8'd0 ), - .adpcmb_addr ( ), // real hardware has 12 pins multiplexed through PMPX pin - .adpcmb_roe_n ( ), // ADPCM-B ROM output enable + .en_hifi_pcm ( 1'b0 ), // used only on YM2612 mode + .adpcma_addr ( ), // real hardware has 10 pins multiplexed through RMPX pin + .adpcma_bank ( ), + .adpcma_roe_n ( ), // ADPCM-A ROM output enable + .adpcma_data ( 8'd0 ), // Data from RAM + .adpcmb_data ( 8'd0 ), + .adpcmb_addr ( ), // real hardware has 12 pins multiplexed through PMPX pin + .adpcmb_roe_n ( ), // ADPCM-B ROM output enable // Separated output .psg_A ( psg_A ), .psg_B ( psg_B ), .psg_C ( psg_C ), - .psg_snd ( psg_snd ), + .psg_snd ( psg_snd ), .fm_snd_left ( fm_snd ), .fm_snd_right (), .adpcmA_l (), @@ -81,7 +100,11 @@ u_jt12( .snd_right ( snd ), .snd_left (), - .snd_sample ( snd_sample ) + .snd_sample ( snd_sample ), + + //.debug_bus ( debug_bus ), + .debug_bus ( 8'd0 ), + .debug_view ( debug_view ) ); -endmodule // jt03 \ No newline at end of file +endmodule // jt03 diff --git a/rtl/jt12/hdl/jt03.yaml b/rtl/jt12/hdl/jt03.yaml new file mode 100644 index 0000000..1fc89ac --- /dev/null +++ b/rtl/jt12/hdl/jt03.yaml @@ -0,0 +1,36 @@ +here: + - jt03.v + - jt12_top.v + - jt03_acc.v + - jt12_single_acc.v + - jt12_eg.v + - jt12_eg_cnt.v + - jt12_eg_comb.v + - jt12_eg_step.v + - jt12_eg_pure.v + - jt12_eg_final.v + - jt12_eg_ctrl.v + - jt12_exprom.v + - jt12_kon.v + - jt12_lfo.v + - jt12_mmr.v + - jt12_div.v + - jt12_mod.v + - jt12_op.v + - jt12_csr.v + - jt12_pg.v + - jt12_pg_inc.v + - jt12_pg_dt.v + - jt12_pg_sum.v + - jt12_pg_comb.v + - jt12_pm.v + - jt12_logsin.v + - jt12_reg.v + - jt12_reg_ch.v + - jt12_sh.v + - jt12_sh_rst.v + - jt12_sh24.v + - jt12_sumch.v + - jt12_timers.v + - jt12_dout.v + - ../jt49/hdl/jt49.yaml diff --git a/rtl/jt12/hdl/jt03_acc.v b/rtl/jt12/hdl/jt03_acc.v index d795a90..89dae34 100644 --- a/rtl/jt12/hdl/jt03_acc.v +++ b/rtl/jt12/hdl/jt03_acc.v @@ -20,12 +20,14 @@ */ -`timescale 1ns / 1ps -/* Use for YM2203 - no left/right channels - full operator resolution - clamped to maximum output of signed 16 bits */ +// Use for YM2203 +// no left/right channels +// full operator resolution +// clamped to maximum output of signed 16 bits +// This version does not clamp each channel individually +// That does not correspond to real hardware behaviour. I should +// change it. module jt03_acc ( @@ -54,17 +56,18 @@ always @(*) begin endcase end -localparam res=18; -wire [res-1:0] hires; -assign snd = hires[res-1:res-16]; - -jt12_single_acc #(.win(14),.wout(res)) u_mono( +// real YM2608 drops the op_result LSB, resulting in a 13-bit accumulator +// but in YM2203, a 13-bit acc for 3 channels only requires 15 bits +// and YM3014 has a 16-bit dynamic range. +// I am leaving the LSB and scaling the output voltage accordingly. This +// should result in less quantification noise. +jt12_single_acc #(.win(14),.wout(16)) u_mono( .clk ( clk ), .clk_en ( clk_en ), .op_result ( op_result ), .sum_en ( sum_en ), .zero ( zero ), - .snd ( hires ) + .snd ( snd ) ); endmodule diff --git a/rtl/jt12/hdl/jt10.v b/rtl/jt12/hdl/jt10.v index 3f5f2b3..b6caa97 100644 --- a/rtl/jt12/hdl/jt10.v +++ b/rtl/jt12/hdl/jt10.v @@ -1,6 +1,6 @@ /* 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 @@ -30,7 +30,7 @@ module jt10( input [1:0] addr, input cs_n, input wr_n, - + output [7:0] dout, output irq_n, // ADPCM pins @@ -40,24 +40,24 @@ module jt10( input [7:0] adpcma_data, // Data from RAM output [23:0] adpcmb_addr, // real hardware has 12 pins multiplexed through PMPX pin output adpcmb_roe_n, // ADPCM-B ROM output enable - input [7:0] adpcmb_data, + input [7:0] adpcmb_data, // Separated output output [ 7:0] psg_A, output [ 7:0] psg_B, output [ 7:0] psg_C, output signed [15:0] fm_snd, // combined output - output [ 9:0] psg_snd, + output [ 9:0] psg_snd, output signed [15:0] snd_right, output signed [15:0] snd_left, output snd_sample, input [3:0] snd_enable, - input [5:0] ch_enable + input [ 5:0] ch_enable // ADPCM-A channels ); // Uses 6 FM channels but only 4 are outputted jt12_top #( - .use_lfo(1),.use_ssg(1), .num_ch(6), .use_pcm(0), .use_adpcm(1), .use_clkdiv(0), + .use_lfo(1),.use_ssg(1), .num_ch(6), .use_pcm(0), .use_adpcm(1), .JT49_DIV(3) ) u_jt12( .rst ( rst ), // rst should be at least 6 clk&cen cycles long @@ -67,7 +67,7 @@ u_jt12( .addr ( addr ), .cs_n ( cs_n ), .wr_n ( wr_n ), - + .dout ( dout ), .irq_n ( irq_n ), // ADPCM pins @@ -75,7 +75,6 @@ u_jt12( .adpcma_bank ( adpcma_bank ), .adpcma_roe_n ( adpcma_roe_n ), // ADPCM-A ROM output enable .adpcma_data ( adpcma_data ), // Data from RAM - .adpcmb_addr ( adpcmb_addr ), // real hardware has 12 pins multiplexed through PMPX pin .adpcmb_roe_n ( adpcmb_roe_n ), // ADPCM-B ROM output enable .adpcmb_data ( adpcmb_data ), // Data from RAM @@ -83,18 +82,31 @@ u_jt12( .psg_A ( psg_A ), .psg_B ( psg_B ), .psg_C ( psg_C ), - .psg_snd ( psg_snd ), + .psg_snd ( psg_snd ), .fm_snd_left ( fm_snd ), - .fm_snd_right (), - + .fm_snd_right ( ), + .adpcmA_l ( ), + .adpcmA_r ( ), + .adpcmB_l ( ), + .adpcmB_r ( ), + // Unused YM2203 + // unused + .IOA_in ( 8'b0 ), + .IOB_in ( 8'b0 ), + .IOA_out ( ), + .IOB_out ( ), + .IOA_oe ( ), + .IOB_oe ( ), + .debug_bus ( 8'd0 ), + // Sound output .snd_right ( snd_right ), .snd_left ( snd_left ), .snd_sample ( snd_sample ), .snd_enable ( snd_enable ), .ch_enable ( ch_enable ), - // unused pins - .en_hifi_pcm ( 1'b0 ) // used only on YM2612 mode + .en_hifi_pcm ( 1'b0 ), // used only on YM2612 mode + .debug_view ( ) ); -endmodule // jt03 \ No newline at end of file +endmodule // jt03 diff --git a/rtl/jt12/hdl/jt10.yaml b/rtl/jt12/hdl/jt10.yaml new file mode 100644 index 0000000..0df2ad4 --- /dev/null +++ b/rtl/jt12/hdl/jt10.yaml @@ -0,0 +1,36 @@ +here: + - jt10.v + - jt10_acc.v + - jt12_top.v + - jt12_single_acc.v + - jt12_eg.v + - jt12_eg_cnt.v + - jt12_eg_comb.v + - jt12_eg_step.v + - jt12_eg_pure.v + - jt12_eg_final.v + - jt12_eg_ctrl.v + - jt12_exprom.v + - jt12_kon.v + - jt12_lfo.v + - jt12_mmr.v + - jt12_div.v + - jt12_mod.v + - jt12_op.v + - jt12_csr.v + - jt12_pg.v + - jt12_pg_inc.v + - jt12_pg_dt.v + - jt12_pg_sum.v + - jt12_pg_comb.v + - jt12_pm.v + - jt12_logsin.v + - jt12_reg.v + - jt12_reg_ch.v + - jt12_sh.v + - jt12_sh_rst.v + - jt12_sh24.v + - jt12_sumch.v + - jt12_timers.v + - jt12_dout.v + - ../jt49/hdl/jt49.yaml diff --git a/rtl/jt12/hdl/jt10_acc.v b/rtl/jt12/hdl/jt10_acc.v index 93d5534..14b5df3 100644 --- a/rtl/jt12/hdl/jt10_acc.v +++ b/rtl/jt12/hdl/jt10_acc.v @@ -139,7 +139,7 @@ jt12_single_acc #(.win(16),.wout(16)) u_right( // Dump each channel independently // It dumps values in decimal, left and right integer f0,f1,f2,f4,f5,f6; -reg signed [15:0] sum_l[7], sum_r[7]; +reg signed [15:0] sum_l[0:7], sum_r[0:7]; initial begin f0=$fopen("fm0.raw","w"); diff --git a/rtl/jt12/hdl/jt12.v b/rtl/jt12/hdl/jt12.v index 409dfee..3262535 100644 --- a/rtl/jt12/hdl/jt12.v +++ b/rtl/jt12/hdl/jt12.v @@ -1,6 +1,6 @@ /* 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 @@ -30,7 +30,7 @@ module jt12 ( input [1:0] addr, input cs_n, input wr_n, - + output [7:0] dout, output irq_n, // configuration @@ -41,7 +41,7 @@ module jt12 ( output snd_sample ); -// Default parameters for JT12 select a YM2610 +// Default parameters for JT12 select a YM2612 jt12_top u_jt12( .rst ( rst ), // rst should be at least 6 clk&cen cycles long .clk ( clk ), // CPU clock @@ -50,8 +50,8 @@ jt12_top u_jt12( .addr ( addr ), .cs_n ( cs_n ), .wr_n ( wr_n ), - - .dout ( dout ), + + .dout ( dout ), .irq_n ( irq_n ), // configuration .en_hifi_pcm ( en_hifi_pcm ), @@ -62,16 +62,31 @@ jt12_top u_jt12( .adpcma_data ( 8'd0 ), // Data from RAM .adpcmb_addr ( ), // real hardware has 12 pins multiplexed through PMPX pin .adpcmb_roe_n ( ), // ADPCM-B ROM output enable + .adpcmb_data ( 8'd0 ), + .ch_enable ( 6'h3f), // Separated output .psg_A (), .psg_B (), .psg_C (), .fm_snd_left (), .fm_snd_right (), + .adpcmA_l ( ), + .adpcmA_r ( ), + .adpcmB_l ( ), + .adpcmB_r ( ), + // Unused YM2203 + .IOA_in ( 8'b0 ), + .IOB_in ( 8'b0 ), + .IOA_out ( ), + .IOB_out ( ), + .IOA_oe ( ), + .IOB_oe ( ), + .debug_bus ( 8'd0 ), // combined output .psg_snd (), .snd_right ( snd_right ), // FM+PSG .snd_left ( snd_left ), // FM+PSG - .snd_sample ( snd_sample ) + .snd_sample ( snd_sample ), + .debug_view ( ) ); -endmodule // jt03 \ No newline at end of file +endmodule // jt03 diff --git a/rtl/jt12/hdl/jt12.yaml b/rtl/jt12/hdl/jt12.yaml new file mode 100644 index 0000000..0b81ceb --- /dev/null +++ b/rtl/jt12/hdl/jt12.yaml @@ -0,0 +1,10 @@ +modules: + other: + - from: jt12/hdl + get: + - "*.v" + - adpcm/*.v + - from: jt12/jt49/hdl + get: + - jt49.yaml + diff --git a/rtl/jt12/hdl/jt12_acc.v b/rtl/jt12/hdl/jt12_acc.v index 8ab86c2..3d59c10 100644 --- a/rtl/jt12/hdl/jt12_acc.v +++ b/rtl/jt12/hdl/jt12_acc.v @@ -100,8 +100,8 @@ jt12_single_acc #(.win(9),.wout(12)) u_right( // Output can be amplied by 8/6=1.33 to use full range // an easy alternative is to add 1/4th and get 1.25 amplification always @(posedge clk) if(clk_en) begin - left <= pre_left + { {2{left [11]}}, left [11:2] }; - right <= pre_right + { {2{right[11]}}, right[11:2] }; + left <= pre_left + { {2{pre_left [11]}}, pre_left [11:2] }; + right <= pre_right + { {2{pre_right[11]}}, pre_right[11:2] }; end endmodule diff --git a/rtl/jt12/hdl/jt12_div.v b/rtl/jt12/hdl/jt12_div.v index 4645e01..4b58315 100644 --- a/rtl/jt12/hdl/jt12_div.v +++ b/rtl/jt12/hdl/jt12_div.v @@ -1,32 +1,35 @@ /* 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 . + Author: Jose Tejada Gomez. Twitter: @topapate Version: 1.0 Date: 14-2-2017 */ -`timescale 1ns / 1ps module jt12_div( input rst, input clk, input cen /* synthesis direct_enable */, - input [1:0] div_setting, - output reg clk_en, // after prescaler - output reg clk_en_2, // cen divided by 2 - output reg clk_en_ssg, - output reg clk_en_666, // 666 kHz - output reg clk_en_111, // 111 kHz - output reg clk_en_55 // 55 kHz + input [1:0] div_setting, + output reg clk_en, // after prescaler + output reg clk_en_2, // cen divided by 2 + output reg clk_en_ssg, + output reg clk_en_666, // 666 kHz + output reg clk_en_111, // 111 kHz + output reg clk_en_55 // 55 kHz ); parameter use_ssg=0; @@ -54,7 +57,6 @@ reg cen_int, cen_ssg_int, cen_adpcm_int, cen_adpcm3_int; // always @(*) begin - casez( div_setting ) 2'b0?: begin // FM 1/2 - SSG 1/1 opn_pres = 4'd2-4'd1; @@ -85,18 +87,18 @@ always @(negedge clk) begin cen_adpcm3_int <= adpcm_cnt111 == 3'd0; cen_55_int <= adpcm_cnt55 == 3'd0; `ifdef FASTDIV - // always enabled for fast sims (use with GYM output, timer will not work well) + // always enabled for fast sims (use with GYM output, the timers will not work well) clk_en <= 1'b1; - clk_en2 <= 1'b1; + clk_en_2 <= 1'b1; clk_en_ssg <= 1'b1; clk_en_666 <= 1'b1; clk_en_55 <= 1'b1; `else - clk_en <= cen & cen_int; + clk_en <= cen & cen_int; clk_en_2 <= cen && (div2==2'b00); clk_en_ssg <= use_ssg ? (cen & cen_ssg_int) : 1'b0; - clk_en_666 <= cen & cen_adpcm_int; - clk_en_111 <= cen & cen_adpcm_int & cen_adpcm3_int; + clk_en_666 <= cen & cen_adpcm_int; + clk_en_111 <= cen & cen_adpcm_int & cen_adpcm3_int; clk_en_55 <= cen & cen_adpcm_int & cen_adpcm3_int & cen_55_int; `endif end @@ -136,4 +138,4 @@ always @(posedge clk) end end -endmodule // jt12_div \ No newline at end of file +endmodule // jt12_div diff --git a/rtl/jt12/hdl/jt12_eg_cnt.v b/rtl/jt12/hdl/jt12_eg_cnt.v index c38ac29..df006d6 100644 --- a/rtl/jt12/hdl/jt12_eg_cnt.v +++ b/rtl/jt12/hdl/jt12_eg_cnt.v @@ -29,7 +29,7 @@ module jt12_eg_cnt( reg [1:0] eg_cnt_base; -always @(posedge clk) begin : envelope_counter +always @(posedge clk, posedge rst) begin : envelope_counter if( rst ) begin eg_cnt_base <= 2'd0; eg_cnt <=15'd0; diff --git a/rtl/jt12/hdl/jt12_eg_ctrl.v b/rtl/jt12/hdl/jt12_eg_ctrl.v index 3b4816b..ddd8698 100644 --- a/rtl/jt12/hdl/jt12_eg_ctrl.v +++ b/rtl/jt12/hdl/jt12_eg_ctrl.v @@ -24,7 +24,7 @@ module jt12_eg_ctrl( input keyoff_now, input [2:0] state_in, input [9:0] eg, - // envelope configuration + // envelope configuration input [4:0] arate, // attack rate input [4:0] rate1, // decay rate input [4:0] rate2, // sustain rate @@ -42,16 +42,16 @@ module jt12_eg_ctrl( output reg pg_rst ); -localparam ATTACK = 3'b001, - DECAY = 3'b010, +localparam ATTACK = 3'b001, + DECAY = 3'b010, HOLD = 3'b100, - RELEASE= 3'b000; // default state is release + RELEASE= 3'b000; // default state is release // wire is_decaying = state_in[1] | state_in[2]; reg [4:0] sustain; -always @(*) +always @(*) if( sl == 4'd15 ) sustain = 5'h1f; // 93dB else @@ -74,14 +74,14 @@ always @(*) begin pg_rst = keyon_now | ssg_pg_rst; end -always @(*) +always @(*) casez ( { keyoff_now, keyon_now, state_in} ) 5'b01_???: begin // key on base_rate = arate; state_next = ATTACK; ssg_inv_out = ssg_att & ssg_en; end - {2'b00, ATTACK}: + {2'b00, ATTACK}: if( eg==10'd0 ) begin base_rate = rate1; state_next = DECAY; @@ -99,7 +99,7 @@ always @(*) ssg_inv_out = ssg_en & (ssg_alt ^ ssg_inv_in); end else begin - base_rate = eg[9:5] >= sustain ? rate2 : rate1; + base_rate = eg[9:5] >= sustain ? rate2 : rate1; // equal comparison according to Nuke state_next = DECAY; ssg_inv_out = ssg_inv_in; end diff --git a/rtl/jt12/hdl/jt12_exprom.v b/rtl/jt12/hdl/jt12_exprom.v index b50e419..beca296 100644 --- a/rtl/jt12/hdl/jt12_exprom.v +++ b/rtl/jt12/hdl/jt12_exprom.v @@ -1,4 +1,3 @@ -`timescale 1ns / 1ps /* This file is part of JT12. diff --git a/rtl/jt12/hdl/jt12_kon.v b/rtl/jt12/hdl/jt12_kon.v index 6b0d608..db4b82c 100644 --- a/rtl/jt12/hdl/jt12_kon.v +++ b/rtl/jt12/hdl/jt12_kon.v @@ -1,4 +1,3 @@ -`timescale 1ns / 1ps /* This file is part of JT12. @@ -61,14 +60,32 @@ if(num_ch==6) begin always @(posedge clk) if( clk_en ) keyon_I <= (csm&&next_ch==3'd2&&overflow2) || csr_out; - wire key_upnow = up_keyon && (keyon_ch==next_ch) && (next_op == 2'd3); + reg up_keyon_reg; + reg [3:0] tkeyon_op; + reg [2:0] tkeyon_ch; + wire key_upnow; + + assign key_upnow = up_keyon_reg && (tkeyon_ch==next_ch) && (next_op == 2'd3); + + always @(posedge clk) if( clk_en ) begin + if (rst) + up_keyon_reg <= 1'b0; + if (up_keyon) begin + up_keyon_reg <= 1'b1; + tkeyon_op <= keyon_op; + tkeyon_ch <= keyon_ch; end + else if (key_upnow) + up_keyon_reg <= 1'b0; + end + + wire middle1; wire middle2; wire middle3; - wire din = key_upnow ? keyon_op[3] : csr_out; - wire mid_din2 = key_upnow ? keyon_op[1] : middle1; - wire mid_din3 = key_upnow ? keyon_op[2] : middle2; - wire mid_din4 = key_upnow ? keyon_op[0] : middle3; + wire din = key_upnow ? tkeyon_op[3] : csr_out; + wire mid_din2 = key_upnow ? tkeyon_op[1] : middle1; + wire mid_din3 = key_upnow ? tkeyon_op[2] : middle2; + wire mid_din4 = key_upnow ? tkeyon_op[0] : middle3; jt12_sh_rst #(.width(1),.stages(6),.rstval(1'b0)) u_konch0( .clk ( clk ), @@ -105,7 +122,7 @@ end else begin // 3 channels reg din; reg [3:0] next_op_hot; - + always @(*) begin case( next_op ) 2'd0: next_op_hot = 4'b0001; // S1 @@ -113,10 +130,10 @@ else begin // 3 channels 2'd2: next_op_hot = 4'b0010; // S2 2'd3: next_op_hot = 4'b1000; // S4 endcase - din = keyon_ch==next_ch && up_keyon ? |(keyon_op&next_op_hot) : csr_out; + din = keyon_ch[1:0]==next_ch[1:0] && up_keyon ? |(keyon_op&next_op_hot) : csr_out; end - always @(posedge clk) if( clk_en ) + always @(posedge clk) if( clk_en ) keyon_I <= csr_out; // No CSM for YM2203 jt12_sh_rst #(.width(1),.stages(12),.rstval(1'b0)) u_konch1( diff --git a/rtl/jt12/hdl/jt12_lfo.v b/rtl/jt12/hdl/jt12_lfo.v index 3f3fa90..7c58efb 100644 --- a/rtl/jt12/hdl/jt12_lfo.v +++ b/rtl/jt12/hdl/jt12_lfo.v @@ -18,7 +18,6 @@ Date: 25-2-2017 */ -`timescale 1ns / 1ps /* diff --git a/rtl/jt12/hdl/jt12_mmr.v b/rtl/jt12/hdl/jt12_mmr.v index ae34867..1f6a121 100644 --- a/rtl/jt12/hdl/jt12_mmr.v +++ b/rtl/jt12/hdl/jt12_mmr.v @@ -18,7 +18,6 @@ Date: 14-2-2017 */ -`timescale 1ns / 1ps module jt12_mmr( input rst, @@ -52,6 +51,7 @@ module jt12_mmr( output reg fast_timers, input flag_A, input overflow_A, + output reg [1:0] div_setting, // PCM output reg [8:0] pcm, output reg pcm_en, @@ -123,13 +123,11 @@ module jt12_mmr( // PSG interace output [3:0] psg_addr, output [7:0] psg_data, - output reg psg_wr_n + output reg psg_wr_n, + input [7:0] debug_bus ); -parameter use_ssg=0, num_ch=6, use_pcm=1, use_adpcm=0, use_clkdiv=1; - -reg [1:0] div_setting; - +parameter use_ssg=0, num_ch=6, use_pcm=1, use_adpcm=0, mask_div=1; jt12_div #(.use_ssg(use_ssg)) u_div ( .rst ( rst ), @@ -183,16 +181,12 @@ reg [ 5:0] latch_fnum; reg [2:0] up_ch; reg [1:0] up_op; -reg old_write; -reg [7:0] din_copy; - -always @(posedge clk) - old_write <= write; +reg [7:0] op_din, ch_din; generate if( use_ssg ) begin assign psg_addr = selected_register[3:0]; - assign psg_data = din_copy; + assign psg_data = ch_din; end else begin assign psg_addr = 4'd0; assign psg_data = 8'd0; @@ -202,88 +196,102 @@ endgenerate reg part; reg [5:0] exbank; +`ifdef SIMULATION +always @(posedge clk) if( write && rst ) begin + $display("WARNING [JT12]: detected write request while in reset.\nThis is likely a glue-logic error in the CPU-FM module."); + $finish; +end +`endif + +wire [2:0] ch_sel = {part, selected_register[1:0]}; + // this runs at clk speed, no clock gating here +// if I try to make this an async rst it fails to map it +// as flip flops but uses latches instead. So I keep it as sync. reset always @(posedge clk) begin : memory_mapped_registers if( rst ) begin - selected_register <= 8'h0; + selected_register <= 0; div_setting <= 2'b10; // FM=1/6, SSG=1/4 - up_ch <= 3'd0; - up_op <= 2'd0; - up_keyon <= 1'd0; - up_opreg <= 7'd0; - up_chreg <= 3'd0; + up_ch <= 0; + up_op <= 0; + up_keyon <= 0; + up_opreg <= 0; + up_chreg <= 0; // IRQ Mask /*{ irq_zero_en, irq_brdy_en, irq_eos_en, irq_tb_en, irq_ta_en } = 5'h1f; */ // timers - { value_A, value_B } <= 18'd0; + { value_A, value_B } <= 0; { clr_flag_B, clr_flag_A, - enable_irq_B, enable_irq_A, load_B, load_A } <= 6'd0; - fast_timers <= 1'b0; + enable_irq_B, enable_irq_A, load_B, load_A } <= 0; + fast_timers <= 0; // LFO - lfo_freq <= 3'd0; - lfo_en <= 1'b0; - csm <= 1'b0; - effect <= 1'b0; + lfo_freq <= 0; + lfo_en <= 0; + csm <= 0; + effect <= 0; // PCM - pcm <= 9'h0; - pcm_en <= 1'b0; - pcm_wr <= 1'b0; + pcm <= 0; + pcm_en <= 0; + pcm_wr <= 0; // ADPCM-A - aon_a <= 'd0; - atl_a <= 'd0; - up_start <= 'd0; - up_end <= 'd0; - up_addr <= 3'd7; - up_lracl <= 3'd7; - up_aon <= 'd0; - lracl <= 'd0; - addr_a <= 'd0; + aon_a <= 0; + atl_a <= 0; + up_start <= 0; + up_end <= 0; + up_addr <= 7; + up_lracl <= 7; + up_aon <= 0; + lracl <= 0; + addr_a <= 0; // ADPCM-B - acmd_on_b <= 'd0; - acmd_rep_b <= 'd0; - acmd_rst_b <= 'd0; - alr_b <= 'd0; - flag_ctl <= 'd0; - astart_b <= 'd0; - aend_b <= 'd0; - adeltan_b <= 'd0; + acmd_on_b <= 0; + acmd_rep_b <= 0; + acmd_rst_b <= 0; + alr_b <= 0; + flag_ctl <= 0; + astart_b <= 0; + aend_b <= 0; + adeltan_b <= 0; + flag_mask <= 0; aeg_b <= 8'hff; // Original test features - eg_stop <= 1'b0; - pg_stop <= 1'b0; - psg_wr_n <= 1'b1; + eg_stop <= 0; + pg_stop <= 0; + psg_wr_n <= 1; // { block_ch3op1, fnum_ch3op1 } <= {3'd0, 11'd0 }; { block_ch3op3, fnum_ch3op3 } <= {3'd0, 11'd0 }; { block_ch3op2, fnum_ch3op2 } <= {3'd0, 11'd0 }; - latch_fnum <= 6'd0; - din_copy <= 8'd0; - part <= 1'b0; + latch_fnum <= 0; + op_din <= 0; + part <= 0; end else begin + up_chreg <= 0; // WRITE IN REGISTERS if( write ) begin if( !addr[0] ) begin selected_register <= din; part <= addr[1]; - if( use_clkdiv==1 ) begin - case(din) - // clock divider: should work only for ym2203 - // and ym2608. - // clock divider works just by selecting the register - REG_CLK_N6: div_setting[1] <= 1'b1; // 2D - REG_CLK_N3: div_setting[0] <= 1'b1; // 2E - REG_CLK_N2: div_setting <= 2'b0; // 2F - default:; - endcase - end + if (!mask_div) + case(din) + // clock divider: should work only for ym2203 + // and ym2608. + // clock divider works just by selecting the register + REG_CLK_N6: div_setting[1] <= 1'b1; // 2D + REG_CLK_N3: div_setting[0] <= 1'b1; // 2E + REG_CLK_N2: div_setting <= 2'b0; // 2F + default:; + endcase end else begin // Global registers - din_copy <= din; - up_keyon <= selected_register == REG_KON && !part; - up_ch <= {part, selected_register[1:0]}; - up_op <= selected_register[3:2]; // 0=S1,1=S3,2=S2,3=S4 - + ch_din <= din; + if( selected_register == REG_KON && !part ) begin + up_keyon <= 1; + op_din <= din; + end else begin + up_keyon <= 0; + end // General control (<0x20 registers and A0==0) if(!part) begin casez( selected_register) @@ -378,17 +386,16 @@ always @(posedge clk) begin : memory_mapped_registers 4'ha: adeltan_b[15:8] <= din; 4'hb: aeg_b <= din; 4'hc: begin - flag_mask <= ~{din[7],din[5:0]}; - flag_ctl <= {din[7],din[5:0]}; // this lasts a single clock cycle - end - + flag_mask <= ~{din[7],din[5:0]}; + flag_ctl <= {din[7],din[5:0]}; // this lasts a single clock cycle + end default:; endcase end end if( selected_register[1:0]==2'b11 ) { up_chreg, up_opreg } <= { 3'h0, 7'h0 }; - else + else begin casez( selected_register ) // channel registers 8'hA0, 8'hA1, 8'hA2: { up_chreg, up_opreg } <= { 3'h1, 7'd0 }; // up_fnumlo @@ -405,6 +412,12 @@ always @(posedge clk) begin : memory_mapped_registers 8'h9?: { up_chreg, up_opreg } <= { 3'h0, 7'h40 }; // up_ssgeg default: { up_chreg, up_opreg } <= { 3'h0, 7'h0 }; endcase // selected_register + if( selected_register[7:4]>=3 && selected_register[7:4]<=9 ) begin + op_din <= din; + up_ch <= {part, selected_register[1:0]}; + up_op <= selected_register[3:2]; // 0=S1,1=S3,2=S2,3=S4 + end + end end end else if(clk_en) begin /* clear once-only bits */ @@ -414,39 +427,44 @@ always @(posedge clk) begin : memory_mapped_registers pcm_wr <= 1'b0; flag_ctl <= 'd0; up_aon <= 1'b0; - acmd_up_b <= 1'b0; + acmd_up_b <= 1'b0; end end end -reg [4:0] busy_cnt; // busy lasts for 32 synth clock cycles, like in real chip +reg [4:0] busy_cnt; // busy lasts for 32 synthesizer clock cycles +wire [5:0] nx_busy = {1'd0,busy_cnt}+{5'd0,busy}; -always @(posedge clk) +always @(posedge clk, posedge rst) begin if( rst ) begin - busy <= 1'b0; - busy_cnt <= 5'd0; - end - else begin - if (!old_write && write && addr[0] ) begin // only set for data writes - busy <= 1'b1; - busy_cnt <= 5'd0; - end - else if(clk_en) begin - if( busy_cnt == 5'd31 ) busy <= 1'b0; - busy_cnt <= busy_cnt+5'd1; + busy <= 0; + busy_cnt <= 0; + end else begin + if( write&addr[0] ) begin + busy <= 1; + busy_cnt <= 0; + end else if(clk_en) begin + busy <= ~nx_busy[5] & busy; + busy_cnt <= nx_busy[4:0]; end end -/* verilator tracing_off */ +end + jt12_reg #(.num_ch(num_ch)) u_reg( .rst ( rst ), .clk ( clk ), // P1 .clk_en ( clk_en ), - .din ( din_copy ), - .up_keyon ( up_keyon ), + // channel udpates + .ch_sel ( ch_sel ), + .ch_din ( ch_din ), .up_fnumlo ( up_chreg[0] ), .up_alg ( up_chreg[1] ), .up_pms ( up_chreg[2] ), + + // operator updates + .din ( op_din ), + .up_keyon ( up_keyon ), .up_dt1 ( up_opreg[0] ), .up_tl ( up_opreg[1] ), .up_ks_ar ( up_opreg[2] ), diff --git a/rtl/jt12/hdl/jt12_mod.v b/rtl/jt12/hdl/jt12_mod.v index 93ac478..2e7bef3 100644 --- a/rtl/jt12/hdl/jt12_mod.v +++ b/rtl/jt12/hdl/jt12_mod.v @@ -1,4 +1,3 @@ -`timescale 1ns / 1ps /* This file is part of JT12. diff --git a/rtl/jt12/hdl/jt12_op.v b/rtl/jt12/hdl/jt12_op.v index 0df0973..d0d2981 100644 --- a/rtl/jt12/hdl/jt12_op.v +++ b/rtl/jt12/hdl/jt12_op.v @@ -1,4 +1,3 @@ -`timescale 1ns / 1ps /* This file is part of JT12. @@ -270,4 +269,63 @@ always @(posedge clk) if( clk_en ) begin op_result_internal <= op_XII; end +`ifdef SIMULATION +reg signed [13:0] op_sep2_0; +reg signed [13:0] op_sep4_0; +reg signed [13:0] op_sep5_0; +reg signed [13:0] op_sep6_0; +reg signed [13:0] op_sep0_0; +reg signed [13:0] op_sep1_0; +reg signed [13:0] op_sep2_1; +reg signed [13:0] op_sep4_1; +reg signed [13:0] op_sep5_1; +reg signed [13:0] op_sep6_1; +reg signed [13:0] op_sep0_1; +reg signed [13:0] op_sep1_1; +reg signed [13:0] op_sep2_2; +reg signed [13:0] op_sep4_2; +reg signed [13:0] op_sep5_2; +reg signed [13:0] op_sep6_2; +reg signed [13:0] op_sep0_2; +reg signed [13:0] op_sep1_2; +reg signed [13:0] op_sep2_3; +reg signed [13:0] op_sep4_3; +reg signed [13:0] op_sep5_3; +reg signed [13:0] op_sep6_3; +reg signed [13:0] op_sep0_3; +reg signed [13:0] op_sep1_3; +reg [ 4:0] sepcnt; + +always @(posedge clk) if(clk_en) begin + sepcnt <= zero ? 5'd0 : sepcnt+5'd1; + case( (sepcnt+14)%24 ) + 0: op_sep0_0 <= op_XII; + 1: op_sep1_0 <= op_XII; + 2: op_sep2_0 <= op_XII; + 3: op_sep4_0 <= op_XII; + 4: op_sep5_0 <= op_XII; + 5: op_sep6_0 <= op_XII; + 6: op_sep0_2 <= op_XII; + 7: op_sep1_2 <= op_XII; + 8: op_sep2_2 <= op_XII; + 9: op_sep4_2 <= op_XII; + 10: op_sep5_2 <= op_XII; + 11: op_sep6_2 <= op_XII; + 12: op_sep0_1 <= op_XII; + 13: op_sep1_1 <= op_XII; + 14: op_sep2_1 <= op_XII; + 15: op_sep4_1 <= op_XII; + 16: op_sep5_1 <= op_XII; + 17: op_sep6_1 <= op_XII; + 18: op_sep0_3 <= op_XII; + 19: op_sep1_3 <= op_XII; + 20: op_sep2_3 <= op_XII; + 21: op_sep4_3 <= op_XII; + 22: op_sep5_3 <= op_XII; + 23: op_sep6_3 <= op_XII; + endcase +end + +`endif + endmodule diff --git a/rtl/jt12/hdl/jt12_pcm.v b/rtl/jt12/hdl/jt12_pcm.v index fda772c..b0d04f5 100644 --- a/rtl/jt12/hdl/jt12_pcm.v +++ b/rtl/jt12/hdl/jt12_pcm.v @@ -41,7 +41,7 @@ always @(posedge clk) reg rate1, rate2; //, rate4, rate8; reg cen1, cen2; //, cen4, cen8; -always @(posedge clk) +always @(posedge clk, posedge rst) if(rst) rate2 <= 1'b0; else begin @@ -56,7 +56,7 @@ always @(posedge clk) end end -always @(negedge clk) begin +always @(posedge clk) begin cen1 <= rate1; cen2 <= rate1 && rate2; // cen4 <= rate1 && rate2 && rate4; diff --git a/rtl/jt12/hdl/jt12_pcm_interpol.v b/rtl/jt12/hdl/jt12_pcm_interpol.v index 14cb1ad..b6f9899 100644 --- a/rtl/jt12/hdl/jt12_pcm_interpol.v +++ b/rtl/jt12/hdl/jt12_pcm_interpol.v @@ -20,17 +20,18 @@ */ module jt12_pcm_interpol -#(parameter dw=9, stepw=5) +#(parameter DW=9, stepw=5) ( input rst_n, input clk, input cen, // 8MHz cen input cen55, // clk & cen55 = 55 kHz input pcm_wr, // advance to next sample - input signed [dw-1:0] pcmin, - output reg signed [dw-1:0] pcmout + input signed [DW-1:0] pcmin, + output reg signed [DW-1:0] pcmout ); +reg sign, last_pcm_wr; reg [stepw-1:0] dn, pre_dn={stepw{1'b1}}; wire posedge_pcmwr = pcm_wr && !last_pcm_wr; wire negedge_pcmwr = !pcm_wr && last_pcm_wr; @@ -38,9 +39,8 @@ wire negedge_pcmwr = !pcm_wr && last_pcm_wr; reg start_div = 0; wire working; -reg signed [dw-1:0] pcmnew, dx, pcmlast, pcminter; -wire signed [dw:0] dx_ext = { pcmin[dw-1], pcmin } - { pcmnew[dw-1], pcmnew }; -reg sign, last_pcm_wr; +reg signed [DW-1:0] pcmnew, dx, pcmlast, pcminter; +wire signed [DW:0] dx_ext = { pcmin[DW-1], pcmin } - { pcmnew[DW-1], pcmnew }; // latch new data and compute the two deltas : dx and dn, slope = dx/dn always @(posedge clk) begin @@ -52,8 +52,8 @@ always @(posedge clk) begin pcmnew <= pcmin; pcmlast <= pcmnew; dn <= pre_dn; - dx <= dx_ext[dw] ? ~dx_ext[dw-1:0] + 'd1 : dx_ext[dw-1:0]; - sign <= dx_ext[dw]; + dx <= dx_ext[DW] ? -dx_ext[DW-1:0] : dx_ext[DW-1:0]; + sign <= dx_ext[DW]; start_div <= 1; end @@ -63,11 +63,11 @@ always @(posedge clk) begin end // interpolate samples -wire [dw-1:0] step; -wire signed [dw-1:0] next_up = pcminter + step; -wire signed [dw-1:0] next_down = pcminter - step; -wire overflow_up = 0;//next_up[dw-1] != pcmnew[dw-1]; -wire overflow_down = 0;//next_down[dw-1] != pcmnew[dw-1]; +wire [DW-1:0] step; +wire signed [DW-1:0] next_up = pcminter + step; +wire signed [DW-1:0] next_down = pcminter - step; +wire overflow_up = 0;//next_up[DW-1] != pcmnew[DW-1]; +wire overflow_down = 0;//next_down[DW-1] != pcmnew[DW-1]; always @(posedge clk) begin @@ -93,13 +93,13 @@ end always @(posedge clk) if(cen55) pcmout <= pcminter; -jt10_adpcm_div #(.dw(dw)) u_div( +jt10_adpcm_div #(.DW(DW)) u_div( .rst_n ( rst_n ), .clk ( clk ), .cen ( 1'b1 ), .start ( start_div ), .a ( dx ), - .b ( { {dw-stepw{1'b0}}, dn } ), + .b ( { {DW-stepw{1'b0}}, dn } ), .d ( step ), .r ( ), .working( working ) diff --git a/rtl/jt12/hdl/jt12_pg.v b/rtl/jt12/hdl/jt12_pg.v index b1e5128..913a739 100644 --- a/rtl/jt12/hdl/jt12_pg.v +++ b/rtl/jt12/hdl/jt12_pg.v @@ -24,7 +24,6 @@ http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc */ -`timescale 1ns / 1ps /* diff --git a/rtl/jt12/hdl/jt12_pg_sum.v b/rtl/jt12/hdl/jt12_pg_sum.v index ca79c2e..6369c53 100644 --- a/rtl/jt12/hdl/jt12_pg_sum.v +++ b/rtl/jt12/hdl/jt12_pg_sum.v @@ -1,49 +1,49 @@ /* 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 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. + 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 . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 2-11-2018 - - Based on information posted by Nemesis on: + You should have received a copy of the GNU General Public License + along with JT12. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 2-11-2018 + + Based on information posted by Nemesis on: http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 - Based on jt51_phasegen.v, from JT51 - - */ + Based on jt51_phasegen.v, from JT51 + + */ module jt12_pg_sum ( - input [ 3:0] mul, - input [19:0] phase_in, - input pg_rst, - input signed [5:0] detune_signed, - input [16:0] phinc_pure, + input [ 3:0] mul, + input [19:0] phase_in, + input pg_rst, + input signed [5:0] detune_signed, + input [16:0] phinc_pure, - output reg [19:0] phase_out, - output reg [ 9:0] phase_op + output reg [19:0] phase_out, + output reg [ 9:0] phase_op ); reg [16:0] phinc_premul; reg [19:0] phinc_mul; always @(*) begin - phinc_premul = phinc_pure + {{11{detune_signed[5]}},detune_signed}; - phinc_mul = ( mul==4'd0 ) ? {4'b0,phinc_premul[16:1]} : ({3'd0,phinc_premul} * mul); - - phase_out = pg_rst ? 20'd0 : (phase_in + { phinc_mul}); - phase_op = phase_out[19:10]; + phinc_premul = phinc_pure + {{11{detune_signed[5]}},detune_signed}; + phinc_mul = ( mul==4'd0 ) ? {4'b0,phinc_premul[16:1]} : ({3'd0,phinc_premul} * mul); + + phase_out = pg_rst ? 20'd0 : (phase_in + { phinc_mul}); + phase_op = phase_out[19:10]; end endmodule // jt12_pg_sum \ No newline at end of file diff --git a/rtl/jt12/hdl/jt12_pm.v b/rtl/jt12/hdl/jt12_pm.v index 5fbb8a0..acfafdc 100644 --- a/rtl/jt12/hdl/jt12_pm.v +++ b/rtl/jt12/hdl/jt12_pm.v @@ -17,9 +17,7 @@ Version: 1.0 Date: 14-10-2018 */ -// altera message_off 10030 -`timescale 1ns / 1ps // This implementation follows that of Alexey Khokholov (Nuke.YKT) in C language. diff --git a/rtl/jt12/hdl/jt12_reg.v b/rtl/jt12/hdl/jt12_reg.v index 89b2017..0b1b4e2 100644 --- a/rtl/jt12/hdl/jt12_reg.v +++ b/rtl/jt12/hdl/jt12_reg.v @@ -24,7 +24,6 @@ module jt12_reg( input rst, input clk, input clk_en /* synthesis direct_enable */, - input [7:0] din, input [2:0] ch, // channel to update input [1:0] op, @@ -33,16 +32,20 @@ module jt12_reg( input flag_A, input overflow_A, - input up_keyon, + // channel udpates + input [2:0] ch_sel, + input [7:0] ch_din, input up_alg, input up_fnumlo, + // operator updates + input [7:0] din, + input up_keyon, input up_pms, input up_dt1, input up_tl, input up_ks_ar, input up_amen_dr, input up_sr, - input up_sl_rr, input up_ssgeg, @@ -181,23 +184,6 @@ wire update_op_IV = cur == req_opch_IV; // key on/off wire [3:0] keyon_op = din[7:4]; wire [2:0] keyon_ch = din[2:0]; -// channel data -wire [2:0] fb_in = din[5:3]; -wire [2:0] alg_in = din[2:0]; -wire [2:0] pms_in = din[2:0]; -wire [1:0] ams_in = din[5:4]; -wire [7:0] fnlo_in = din; - - -wire update_ch_I = cur_ch == ch; -wire update_ch_IV = num_ch==6 ? - { ~cur_ch[2], cur_ch[1:0]} == ch : // 6 channels - cur[1:0] == ch[1:0]; // 3 channels - -wire up_alg_ch = up_alg & update_ch_I; -wire up_fnumlo_ch=up_fnumlo & update_ch_I; -wire up_pms_ch = up_pms & update_ch_I; -wire up_ams_ch = up_pms & update_ch_IV; always @(*) begin // next = cur==5'd23 ? 5'd0 : cur +1'b1; @@ -327,46 +313,27 @@ assign { tl_IV, dt1_I, mul_II, ks_II, // memory for CH registers -// Block/fnum data is latched until fnum low byte is written to -// Trying to synthesize this memory as M-9K RAM in Altera devices -// turns out worse in terms of resource utilization. Probably because -// this memory is already very small. It is better to leave it as it is. -localparam regch_width=25; -wire [regch_width-1:0] regch_out; -wire [regch_width-1:0] regch_in = { - up_fnumlo_ch? { latch_fnum, fnlo_in } : { block_I_raw, fnum_I_raw }, // 14 - up_alg_ch ? { fb_in, alg_in } : { fb_I, alg_I },//3+3 - up_ams_ch ? ams_in : ams_IV, //2 - up_pms_ch ? pms_in : pms_I //3 -}; +jt12_reg_ch #(.NUM_CH(num_ch)) u_regch( + .rst ( rst ), + .clk ( clk ), + .cen ( clk_en ), + .din ( ch_din ), -assign { block_I_raw, fnum_I_raw, - fb_I, alg_I, ams_IV, pms_I } = regch_out; + .up_ch ( ch_sel ), + .latch_fnum ( latch_fnum ), + .up_fnumlo ( up_fnumlo ), + .up_alg ( up_alg ), + .up_pms ( up_pms ), -jt12_sh_rst #(.width(regch_width),.stages(num_ch)) u_regch( - .clk ( clk ), - .clk_en ( clk_en ), - .rst ( rst ), - .din ( regch_in ), - .drop ( regch_out ) + .ch ( next_ch ), // next active channel + .block ( block_I_raw ), + .fnum ( fnum_I_raw ), + .fb ( fb_I ), + .alg ( alg_I ), + .rl ( rl ), + .ams_IV ( ams_IV ), + .pms ( pms_I ) ); -generate -if( num_ch==6 ) begin - // RL is on a different register to - // have the reset to 1 - wire [1:0] rl_in = din[7:6]; - jt12_sh_rst #(.width(2),.stages(num_ch),.rstval(1'b1)) u_regch_rl( - .clk ( clk ), - .clk_en ( clk_en ), - .rst ( rst ), - .din ( up_pms_ch ? rl_in : rl ), - .drop ( rl ) - ); -end else begin // YM2203 has no stereo output - assign rl=2'b11; -end - -endgenerate `endif endmodule diff --git a/rtl/jt12/hdl/jt12_reg_ch.v b/rtl/jt12/hdl/jt12_reg_ch.v new file mode 100644 index 0000000..d3f5b2e --- /dev/null +++ b/rtl/jt12/hdl/jt12_reg_ch.v @@ -0,0 +1,128 @@ +/* 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 . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 23-10-2019 + */ + +// Channel data is not stored in a CSR as operators +// Proof of that is the Splatter House arcade writes +// channel and operator data in two consequitive accesses +// without enough time in between to have the eight +// channels go through the CSR. So the channel data +// cannot be CSR, but regular registers. +module jt12_reg_ch( + input rst, + input clk, + input cen, + input [ 7:0] din, + + input [ 2:0] up_ch, + input [ 5:0] latch_fnum, + input up_fnumlo, + input up_alg, + input up_pms, + + input [ 2:0] ch, // next active channel + output reg [ 2:0] block, + output reg [10:0] fnum, + output reg [ 2:0] fb, + output reg [ 2:0] alg, + output reg [ 1:0] rl, + output reg [ 1:0] ams_IV, + output reg [ 2:0] pms +); + +parameter NUM_CH=6; +localparam M=NUM_CH==3?2:3; + +reg [ 2:0] reg_block[0:NUM_CH-1]; +reg [10:0] reg_fnum [0:NUM_CH-1]; +reg [ 2:0] reg_fb [0:NUM_CH-1]; +reg [ 2:0] reg_alg [0:NUM_CH-1]; +reg [ 1:0] reg_rl [0:NUM_CH-1]; +reg [ 1:0] reg_ams [0:NUM_CH-1]; +reg [ 2:0] reg_pms [0:NUM_CH-1]; +reg [ 2:0] ch_IV; + +wire [M-1:0] ch_sel, out_sel; + +function [M-1:0] chtr( input [2:0] chin ); +reg [2:0] aux; +begin + aux = chin[M-1] ? {1'b0,chin[1:0]}+3'd3 : // upper channels + {1'b0,chin[1:0]}; // lower + chtr = NUM_CH==3 ? chin[M-1:0] : aux[M-1:0]; + +end +endfunction + +assign ch_sel = chtr(up_ch); +assign out_sel = chtr(ch); + +integer i; +/* verilator lint_off WIDTHEXPAND */ +always @* begin + ch_IV = ch; + if( NUM_CH==6 ) + case(out_sel) + 0: ch_IV = 3; + 1: ch_IV = 4; + 2: ch_IV = 5; + 3: ch_IV = 0; + 4: ch_IV = 1; + 5: ch_IV = 2; + default: ch_IV = 0; + endcase +end +/* verilator lint_on WIDTHEXPAND */ + +always @(posedge clk) if(cen) begin + block <= reg_block[out_sel]; + fnum <= reg_fnum [out_sel]; + fb <= reg_fb [out_sel]; + alg <= reg_alg [out_sel]; + rl <= reg_rl [out_sel]; + ams_IV<= reg_ams [ch_IV[M-1:0]]; + pms <= reg_pms [out_sel]; + if( NUM_CH==3 ) rl <= 3; // YM2203 has no stereo output +end + +always @(posedge clk, posedge rst) begin + if( rst ) for(i=0;i. + You should have received a copy of the GNU General Public License + along with JT12. If not, see . - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 14-2-2017 + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 14-2-2017 - YM3438_APL.pdf - Timer A = 144*(1024-NA)/Phi M - Timer B = 2304*(256-NB)/Phi M - */ + YM3438_APL.pdf + Timer A = 144*(1024-NA)/Phi M + Timer B = 2304*(256-NB)/Phi M + */ -`timescale 1ns / 1ps module jt12_timers( - input clk, - input rst, - input clk_en /* synthesis direct_enable */, - input [9:0] value_A, - input [7:0] value_B, - input load_A, - input load_B, - input clr_flag_A, - input clr_flag_B, - input enable_irq_A, - input enable_irq_B, - output flag_A, - output flag_B, - output overflow_A, - output irq_n + input clk, + input rst, + input clk_en /* synthesis direct_enable */, + input zero, + input [9:0] value_A, + input [7:0] value_B, + input load_A, + input load_B, + input clr_flag_A, + input clr_flag_B, + input enable_irq_A, + input enable_irq_B, + output flag_A, + output flag_B, + output overflow_A, + output irq_n ); +parameter num_ch = 6; + assign irq_n = ~( (flag_A&enable_irq_A) | (flag_B&enable_irq_B) ); -jt12_timer #(.mult_width(5), .mult_max(24), .counter_width(10)) -timer_A( - .clk ( clk ), - .rst ( rst ), - .clk_en ( clk_en ), - .start_value( value_A ), - .load ( load_A ), - .clr_flag ( clr_flag_A), - .flag ( flag_A ), - .overflow ( overflow_A) -); +/* +reg zero2; -jt12_timer #(.mult_width(9), .mult_max(384), .counter_width(8)) -timer_B( - .clk ( clk ), - .rst ( rst ), - .clk_en ( clk_en ), - .start_value( value_B ), - .load ( load_B ), - .clr_flag ( clr_flag_B), - .flag ( flag_B ), - .overflow ( ) -); - -endmodule - -module jt12_timer #(parameter counter_width = 10, mult_width=5, mult_max=4 ) -( - input clk, - input rst, -(* direct_enable *) input clk_en, - input [counter_width-1:0] start_value, - input load, - input clr_flag, - output reg flag, - output reg overflow -); - -reg [ mult_width-1:0] mult; -reg [counter_width-1:0] cnt; - -always@(posedge clk) - if( clr_flag || rst) - flag <= 1'b0; - else if(overflow) flag<=1'b1; - -reg [mult_width+counter_width-1:0] next, init; - -always @(*) begin - if( mult+1'b1 252 x4 jt12_interpol #(.calcw(17),.inw(16),.rate(4),.m(1),.n(1)) diff --git a/rtl/jt12/hdl/mixer/jt12_genmix.v b/rtl/jt12/hdl/mixer/jt12_genmix.v index 6cddf7f..1963fdc 100644 --- a/rtl/jt12/hdl/mixer/jt12_genmix.v +++ b/rtl/jt12/hdl/mixer/jt12_genmix.v @@ -75,7 +75,7 @@ always @(posedge clk) end reg psg_cen_1008, psg_cen_240, psg_cen_48, psg_cen_144; -always @(negedge clk) begin +always @(posedge clk) begin psg_cen_240 <= psgcnt48 ==6'd47 && psgcnt240 == 3'd0; psg_cen_48 <= psgcnt48 ==6'd47; psg_cen_144 <= psgcnt48 ==6'd47 && psgcnt144==2'd0; @@ -144,7 +144,7 @@ always @(posedge clk) end // evenly spaced clock enable signals reg cen_1008, cen_252, cen_63, cen_9; -always @(negedge clk) begin +always @(posedge clk) begin cen_9 <= clkcnt9 ==4'd8; cen_63 <= clkcnt9 ==4'd8 && clkcnt63 ==3'd0; cen_252 <= clkcnt9 ==4'd8 && clkcnt63 ==3'd0 && clkcnt252 ==2'd0; diff --git a/rtl/jt12/hdl/mixer/jt12_mixer.v b/rtl/jt12/hdl/mixer/jt12_mixer.v index 27fcd4a..447babc 100644 --- a/rtl/jt12/hdl/mixer/jt12_mixer.v +++ b/rtl/jt12/hdl/mixer/jt12_mixer.v @@ -81,4 +81,4 @@ always @(posedge clk) if(cen) begin mixed <= limited[wout-1:0]; end -endmodule // jt12_mixer \ No newline at end of file +endmodule // jt12_mixer diff --git a/rtl/jt12/hdl/jt03.qip b/rtl/jt12/target/quartus/jt03.qip similarity index 57% rename from rtl/jt12/hdl/jt03.qip rename to rtl/jt12/target/quartus/jt03.qip index 4ccac17..af18c62 100644 --- a/rtl/jt12/hdl/jt03.qip +++ b/rtl/jt12/target/quartus/jt03.qip @@ -1,40 +1,36 @@ -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03.v ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_dout.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49_exp.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49_noise.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../jt49/hdl/jt49_cen.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt03.v ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../../hdl/jt12.vhd ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_top.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt03_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_single_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_step.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_pure.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_final.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_ctrl.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_exprom.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_kon.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_lfo.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mmr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mod.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_op.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_csr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_inc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_dt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_sum.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_logsin.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg_ch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh24.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sumch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_timers.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_dout.v ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) ../../jt49/syn/quartus/jt49.qip ] diff --git a/rtl/jt12/hdl/jt03_fm.qip b/rtl/jt12/target/quartus/jt03_fm.qip similarity index 65% rename from rtl/jt12/hdl/jt03_fm.qip rename to rtl/jt12/target/quartus/jt03_fm.qip index 312a4cc..67166e2 100644 --- a/rtl/jt12/hdl/jt03_fm.qip +++ b/rtl/jt12/target/quartus/jt03_fm.qip @@ -1,33 +1,33 @@ -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03.v ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt03_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt03.v ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../../hdl/jt12.vhd ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_top.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt03_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_single_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_step.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_pure.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_final.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_ctrl.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_exprom.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_kon.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_lfo.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mmr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mod.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_op.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_csr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_inc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_dt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_sum.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_logsin.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh24.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sumch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_timers.v ] diff --git a/rtl/jt12/hdl/jt10.qip b/rtl/jt12/target/quartus/jt10.qip similarity index 62% rename from rtl/jt12/hdl/jt10.qip rename to rtl/jt12/target/quartus/jt10.qip index 20d2dff..e426f0d 100644 --- a/rtl/jt12/hdl/jt10.qip +++ b/rtl/jt12/target/quartus/jt10.qip @@ -1,56 +1,57 @@ -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt10.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pcm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_genmix.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_decim.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_fm_uprate.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_dout.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt10.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mmr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_top.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_single_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_step.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_pure.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_final.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_ctrl.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_exprom.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_kon.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_lfo.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mod.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_op.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_csr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_inc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_dt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_sum.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_logsin.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg_ch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh24.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sumch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_timers.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pcm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_genmix.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_decim.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_interpol.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_fm_uprate.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_dout.v ] # ADPCM -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcma_lut.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcmb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcmb_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcmb_gain.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_dbrom.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_drvA.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_drvB.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_gain.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_cen_burst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcmb_interpol.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt10_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcma_lut.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcmb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcmb_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcmb_gain.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_dbrom.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_drvA.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_drvB.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_gain.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_cen_burst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcmb_interpol.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt10_acc.v ] diff --git a/rtl/jt12/hdl/jt12.qip b/rtl/jt12/target/quartus/jt12.qip similarity index 64% rename from rtl/jt12/hdl/jt12.qip rename to rtl/jt12/target/quartus/jt12.qip index 8c5eb8f..eeea9f1 100644 --- a/rtl/jt12/hdl/jt12.qip +++ b/rtl/jt12/target/quartus/jt12.qip @@ -1,42 +1,42 @@ -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) jt12.vhd ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_top.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_single_acc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_cnt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_step.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_pure.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_final.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg_ctrl.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_csr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_inc.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_dt.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_sum.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg_comb.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pm.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_logsin.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pcm_interpol.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_dout.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_rst.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) adpcm/jt10_adpcm_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_genmix.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mixer/jt12_decim.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_fm_uprate.v ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ../../hdl/jt12.vhd ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_top.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_single_acc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_cnt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_step.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_pure.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_final.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_eg_ctrl.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_exprom.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_kon.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_lfo.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mod.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_op.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_csr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_inc.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_dt.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_sum.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pg_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pm.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_logsin.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_reg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sh24.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_sumch.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_timers.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_pcm_interpol.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_mmr.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_dout.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt12_rst.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/adpcm/jt10_adpcm_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_genmix.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_decim.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_interpol.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_comb.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/mixer/jt12_fm_uprate.v ] diff --git a/rtl/jt49/README.md b/rtl/jt49/README.md index a6ca26b..025682a 100644 --- a/rtl/jt49/README.md +++ b/rtl/jt49/README.md @@ -1,12 +1,33 @@ # JT49 FPGA Clone of YM2149 hardware by Jose Tejada (@topapate) You can show your appreciation through -* [Patreon](https://patreon.com/topapate), by supporting releases -* [Paypal](https://paypal.me/topapate), with a donation +* [Patreon](https://patreon.com/jotego), by supporting open source retro releases YM2149 compatible Verilog core, with emphasis on FPGA implementation as part of JT12 in order to recreate the YM2203 part. +## Documentation + +- [AY-3-8910 Data Manual](https://archive.org/details/AY-3-8910-8912_Feb-1979/page/n51/mode/2up) +- [AY-3-8919 Reverse Engineered](https://github.com/lvd2/ay-3-8910_reverse_engineered) +- [YM2149](https://archive.org/details/bitsavers_yamahaYM21_3070829) + +## Using JT49 in a git project + +If you are using JT49 in a git project, the best way to add it to your project is: + +1. Optionally fork JT49's repository to your own GitHub account +2. Add it as a submodule to your git project: `git submodule add https://github.com/jotego/jt49.git` +3. Now you can refer to the RTL files in **jt49/hdl** + +The advantages of a using a git submodule are: + +1. Your project contains a reference to a commit of the JT49 repository +2. As long as you do not manually update the JT49 submodule, it will keep pointing to the same commit +3. Each time you make a commit in your project, it will include a pointer to the JT49 commit used. So you will always know the JT49 that worked for you +4. If JT49 is updated and you want to get the changes, simply update the submodule using git. The new JT49 commit used will be annotated in your project's next commit. So the history of your project will reflect that change too. +5. JT49 files will be intact and you will use the files without altering them. + ## Usage There are two top level files you can use: @@ -15,6 +36,13 @@ There are two top level files you can use: clk_en cannot be set to 1 for correct operation. The design assumes that there will be at least one empty clock cycle between every two clk_en high clock cycles. +## Files for Simulation and Synthesis + +When used inside a [JTFRAME](https://github.com/jotego/jtframe) project, you can use the [yaml](hdl/jt49.yaml) file provided. If you are using this repository on its own, there is a [qip](syn/quartus/jt49.qip) for Intel Quartus available. + +It is recommended to use this repository as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) in your project. + + ## Port Description jt49 Name | Direction | Width | Purpose @@ -69,16 +97,35 @@ envelope period | Yes | Tested 0 and FFF values ## Resistor Load Modelling -The resistor load had an effect of gain compression on the chip. There is a parameter called **COMP** which can be used to model this effect. You can assign a value from 0 to 3. +The YM2149 was used to measure the output circuitry. According to AY-3-8910 schematics, there are 16 NMOS devices for each channel. Depending on the amplitude settings, only one of them will be active. These numbers render values that agree with the datasheet and measurements: -Value | Dynamic Range | Equivalent resistor -------|---------------|-------------------- - 0 | 43.6 dB | <1000 Ohm - 1 | 29.1 dB | ~8000 Ohm - 2 | 21.8 dB | ~40 kOhm (?) - 3 | 13.4 dB | ~99 kOhm +- Rload = 1 kOhm +- Smallest Ron = 900 Ohm (for level=15) +- Largest Roff = 3 MOhm (for level=0) +- Scale factor from one MOS to the next = 1.55 + +Each output level is the combination of one MOS being on and the rest off, so they combine into a single impedance, which then forms a resistor divider with the load. + +The output MOS will hold its impedance even if an extra 1V is added at the load resistor (reducing the MOS headroom) ## Non Linear Effects -- Saturation effects are not modelled -- Channel mixing effects by short circuiting the outputs are not modelled +- Channel mixing effects by short circuiting the outputs in AY-3-8910 are not modelled +- Non linearity in YM2203 when shorting all outputs is modeled via parameter YM2203_LUMPED + +Non linear effects depend on the way the chip is connected and its model. See [the connection list](doc/conn.md). + +## Related Projects + +Other sound chips from the same author + +Chip | Repository +-----------------------|------------ +YM2203, YM2612, YM2610 | [JT12](https://github.com/jotego/jt12) +YM2151 | [JT51](https://github.com/jotego/jt51) +YM3526 | [JTOPL](https://github.com/jotego/jtopl) +YM2149 | [JT49](https://github.com/jotego/jt49) +sn76489an | [JT89](https://github.com/jotego/jt89) +OKI 6295 | [JT6295](https://github.com/jotego/jt6295) +OKI MSM5205 | [JT5205](https://github.com/jotego/jt5205) +NEC uPN7759 | [JT7759](https://github.com/jotego/jt7759) \ No newline at end of file diff --git a/rtl/jt49/hdl/filter/jt49_dcrm.v b/rtl/jt49/hdl/filter/jt49_dcrm.v index e84f2b1..32d4660 100644 --- a/rtl/jt49/hdl/filter/jt49_dcrm.v +++ b/rtl/jt49/hdl/filter/jt49_dcrm.v @@ -22,7 +22,7 @@ // DC removal filter // input is unsigned // output is signed - +/* verilator tracing_off */ module jt49_dcrm( input clk, input cen, diff --git a/rtl/jt49/hdl/filter/jt49_dcrm2.v b/rtl/jt49/hdl/filter/jt49_dcrm2.v index 6646a30..f775d03 100644 --- a/rtl/jt49/hdl/filter/jt49_dcrm2.v +++ b/rtl/jt49/hdl/filter/jt49_dcrm2.v @@ -31,20 +31,20 @@ module jt49_dcrm2 #(parameter sw=8) ( output signed [sw-1:0] dout ); -localparam dw=10; // width of the decimal portion +localparam DW=10; // width of the decimal portion -reg signed [sw+dw:0] integ, exact, error; -//reg signed [2*(9+dw)-1:0] mult; -// wire signed [sw+dw:0] plus1 = { {sw+dw{1'b0}},1'b1}; +reg signed [sw+DW:0] integ, exact, error; +//reg signed [2*(9+DW)-1:0] mult; +// wire signed [sw+DW:0] plus1 = { {sw+DW{1'b0}},1'b1}; reg signed [sw:0] pre_dout; -// reg signed [sw+dw:0] dout_ext; +// reg signed [sw+DW:0] dout_ext; reg signed [sw:0] q; always @(*) begin exact = integ+error; - q = exact[sw+dw:dw]; + q = exact[sw+DW:DW]; pre_dout = { 1'b0, din } - q; - //dout_ext = { pre_dout, {dw{1'b0}} }; + //dout_ext = { pre_dout, {DW{1'b0}} }; //mult = dout_ext; end @@ -52,13 +52,13 @@ assign dout = pre_dout[sw-1:0]; always @(posedge clk) if( rst ) begin - integ <= {sw+dw+1{1'b0}}; - error <= {sw+dw+1{1'b0}}; + integ <= {sw+DW+1{1'b0}}; + error <= {sw+DW+1{1'b0}}; end else if( cen ) begin /* verilator lint_off WIDTH */ - integ <= integ + pre_dout; //mult[sw+dw*2:dw]; + integ <= integ + pre_dout; //mult[sw+DW*2:DW]; /* verilator lint_on WIDTH */ - error <= exact-{q, {dw{1'b0}}}; + error <= exact-{q, {DW{1'b0}}}; end endmodule \ No newline at end of file diff --git a/rtl/jt49/hdl/filter/jt49_dly.v b/rtl/jt49/hdl/filter/jt49_dly.v index 7142ec9..3ac2541 100644 --- a/rtl/jt49/hdl/filter/jt49_dly.v +++ b/rtl/jt49/hdl/filter/jt49_dly.v @@ -22,7 +22,7 @@ // Delay stage // use for long delays -module jt49_dly #(parameter dw=8, depth=10)( +module jt49_dly #(parameter DW=8, depth=10)( input clk, input cen, input rst, @@ -36,10 +36,10 @@ reg [depth-1:0] rdpos, wrpos; // memory -reg [dw-1:0] ram[0:2**depth-1]; +reg [DW-1:0] ram[0:2**depth-1]; always @(posedge clk) if(rst) - pre_dout <= {dw{1'b0}}; + pre_dout <= {DW{1'b0}}; else begin pre_dout <= ram[rdpos]; if( cen ) ram[wrpos] <= din; @@ -57,7 +57,7 @@ always @(posedge clk) if( rst ) begin rdpos <= { {depth-1{1'b0}}, 1'b1}; wrpos <= {depth{1'b1}}; - dout <= {dw{1'b0}}; + dout <= {DW{1'b0}}; end else if(cen) begin dout <= pre_dout; rdpos <= rdpos+1'b1; diff --git a/rtl/jt49/hdl/filter/jt49_mave.v b/rtl/jt49/hdl/filter/jt49_mave.v index 2d02393..02a0916 100644 --- a/rtl/jt49/hdl/filter/jt49_mave.v +++ b/rtl/jt49/hdl/filter/jt49_mave.v @@ -21,18 +21,18 @@ // Moving averager -module jt49_mave #(parameter depth=8, dw=8)( +module jt49_mave #(parameter depth=8, DW=8)( input clk, input cen, input rst, - input signed [dw-1:0] din, - output signed [dw-1:0] dout + input signed [DW-1:0] din, + output signed [DW-1:0] dout ); -wire [dw-1:0] dly0; -wire [dw-1:0] pre_dly0; +wire [DW-1:0] dly0; +wire [DW-1:0] pre_dly0; -jt49_dly #(.depth(depth),.dw(dw)) u_dly0( +jt49_dly #(.depth(depth),.DW(DW)) u_dly0( .clk ( clk ), .cen ( cen ), .rst ( rst ), @@ -43,18 +43,18 @@ jt49_dly #(.depth(depth),.dw(dw)) u_dly0( // moving average // D=2048 -reg signed [dw:0] diff; -reg signed [dw+depth-1:0] sum; +reg signed [DW:0] diff; +reg signed [DW+depth-1:0] sum; always @(posedge clk) if( rst ) begin - diff <= {dw+1{1'd0}}; - sum <= {dw+depth+1{1'd0}}; + diff <= {DW+1{1'd0}}; + sum <= {DW+depth+1{1'd0}}; end else if(cen) begin diff <= {1'b0,din } - { 1'b0, dly0 }; - sum <= { {depth{diff[dw]}}, diff } + sum; + sum <= { {depth{diff[DW]}}, diff } + sum; end -assign dout = sum[dw+depth-1:depth]; +assign dout = sum[DW+depth-1:depth]; endmodule \ No newline at end of file diff --git a/rtl/jt49/hdl/jt49.v b/rtl/jt49/hdl/jt49.v index bcc9a71..08145bf 100644 --- a/rtl/jt49/hdl/jt49.v +++ b/rtl/jt49/hdl/jt49.v @@ -35,22 +35,24 @@ module jt49 ( // note that input ports are not multiplexed output reg [7:0] A, // linearised channel output output reg [7:0] B, output reg [7:0] C, + output sample, input [7:0] IOA_in, output [7:0] IOA_out, + output IOA_oe, input [7:0] IOB_in, - output [7:0] IOB_out + output [7:0] IOB_out, + output IOB_oe ); -parameter [1:0] COMP=2'b00; +parameter [2:0] COMP=3'b000; +parameter YM2203_LUMPED=0; parameter CLKDIV=3; -wire [1:0] comp = COMP; +wire [2:0] comp = COMP; -reg [7:0] regarray[15:0]; - -assign IOA_out = regarray[14]; -assign IOB_out = regarray[15]; +reg [7:0] regarray[15:0]; +wire [7:0] port_A, port_B; wire [4:0] envelope; wire bitA, bitB, bitC; @@ -59,6 +61,14 @@ reg Amix, Bmix, Cmix; wire cen16, cen256; +assign IOA_out = regarray[14]; +assign IOB_out = regarray[15]; +assign port_A = IOA_in; +assign port_B = IOB_in; +assign IOA_oe = regarray[7][6]; +assign IOB_oe = regarray[7][7]; +assign sample = cen16; + jt49_cen #(.CLKDIV(CLKDIV)) u_cen( .clk ( clk ), .rst_n ( rst_n ), @@ -159,7 +169,10 @@ always @(posedge clk) if( clk_en ) begin logC <= !Cmix ? 5'd0 : (use_envC ? envelope : volC ); end -reg [9:0] acc; +reg [9:0] acc; +wire [9:0] elin; + +assign elin = {2'd0,lin}; always @(posedge clk, negedge rst_n) begin if( !rst_n ) begin @@ -171,7 +184,9 @@ always @(posedge clk, negedge rst_n) begin sound <= 10'd0; end else if(clk_en) begin acc_st <= { acc_st[2:0], acc_st[3] }; - acc <= acc + {2'b0,lin}; + // Lumping the channel outputs for YM2203 will cause only the higher + // voltage to pass throuh, as the outputs seem to use a source follower. + acc <= YM2203_LUMPED==1 ? (acc>elin ? acc : elin) : acc + elin; case( acc_st ) 4'b0001: begin log <= logA; @@ -194,7 +209,7 @@ always @(posedge clk, negedge rst_n) begin end end -reg [7:0] read_mask; +reg [7:0] read_mask; always @(*) case(addr) @@ -226,8 +241,8 @@ always @(posedge clk, negedge rst_n) begin last_write <= write; // Data read case( addr ) - 4'he: dout <= !regarray[7][6] ? IOA_in : 8'hff; - 4'hf: dout <= !regarray[7][7] ? IOB_in : 8'hff; + 4'he: dout <= port_A; + 4'hf: dout <= port_B; default: dout <= regarray[ addr ] & read_mask; endcase // Data write diff --git a/rtl/jt49/hdl/jt49.yaml b/rtl/jt49/hdl/jt49.yaml new file mode 100644 index 0000000..8db6730 --- /dev/null +++ b/rtl/jt49/hdl/jt49.yaml @@ -0,0 +1,8 @@ +here: + - jt49.v + - jt49_bus.v + - jt49_div.v + - jt49_cen.v + - jt49_eg.v + - jt49_exp.v + - jt49_noise.v diff --git a/rtl/jt49/hdl/jt49_bus.v b/rtl/jt49/hdl/jt49_bus.v index 0937abd..ac48e8e 100644 --- a/rtl/jt49/hdl/jt49_bus.v +++ b/rtl/jt49/hdl/jt49_bus.v @@ -12,16 +12,16 @@ You should have received a copy of the GNU General Public License along with JT49. If not, see . - + 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 +// This is a wrapper with the BDIR/BC1 pins module jt49_bus ( // note that input ports are not multiplexed input rst_n, @@ -38,22 +38,25 @@ module jt49_bus ( // note that input ports are not multiplexed output [7:0] A, // linearised channel output output [7:0] B, output [7:0] C, + output sample, input [7:0] IOA_in, output [7:0] IOA_out, + output IOA_oe, input [7:0] IOB_in, - output [7:0] IOB_out + output [7:0] IOB_out, + output IOB_oe ); -parameter [1:0] COMP=2'b00; +parameter [2:0] COMP=3'b000; reg wr_n, cs_n; reg [3:0] addr; reg addr_ok; reg [7:0] din_latch; -always @(posedge clk) +always @(posedge clk) if( !rst_n ) begin wr_n <= 1'b1; cs_n <= 1'b1; @@ -87,13 +90,16 @@ jt49 #(.COMP(COMP)) u_jt49( // note that input ports are not multiplexed .sel ( sel ), // if sel is low, the clock is divided by 2 .dout ( dout ), .sound ( sound ), // combined channel output + .sample ( sample ), .A ( A ), // linearised channel output .B ( B ), .C ( C ), .IOA_in ( IOA_in ), .IOA_out( IOA_out ), + .IOA_oe ( IOA_oe ), .IOB_in ( IOB_in ), - .IOB_out( IOB_out ) + .IOB_out( IOB_out ), + .IOB_oe ( IOB_oe ) ); endmodule // jt49_bus \ No newline at end of file diff --git a/rtl/jt49/hdl/jt49_exp.v b/rtl/jt49/hdl/jt49_exp.v index 8fa4d35..25efa38 100644 --- a/rtl/jt49/hdl/jt49_exp.v +++ b/rtl/jt49/hdl/jt49_exp.v @@ -21,10 +21,6 @@ */ -// altera message_off 10030 - -`timescale 1ns / 1ps - // Compression vs dynamic range // 0 -> 43.6dB // 1 -> 29.1 @@ -33,12 +29,12 @@ module jt49_exp( input clk, - input [1:0] comp, // compression + input [2:0] comp, // compression input [4:0] din, output reg [7:0] dout ); -reg [7:0] lut[0:127]; +reg [7:0] lut[0:159]; always @(posedge clk) dout <= lut[ {comp,din} ]; @@ -172,6 +168,38 @@ initial begin lut[125] = 8'd229; lut[126] = 8'd241; lut[127] = 8'd255; + lut[128] = 8'd0; + lut[129] = 8'd8; + lut[130] = 8'd10; + lut[131] = 8'd12; + lut[132] = 8'd16; + lut[133] = 8'd22; + lut[134] = 8'd29; + lut[135] = 8'd35; + lut[136] = 8'd44; + lut[137] = 8'd50; + lut[138] = 8'd56; + lut[139] = 8'd60; + lut[140] = 8'd64; + lut[141] = 8'd85; + lut[142] = 8'd97; + lut[143] = 8'd103; + lut[144] = 8'd108; + lut[145] = 8'd120; + lut[146] = 8'd127; + lut[147] = 8'd134; + lut[148] = 8'd141; + lut[149] = 8'd149; + lut[150] = 8'd157; + lut[151] = 8'd166; + lut[152] = 8'd175; + lut[153] = 8'd185; + lut[154] = 8'd195; + lut[155] = 8'd206; + lut[156] = 8'd217; + lut[157] = 8'd229; + lut[158] = 8'd241; + lut[159] = 8'd255; end endmodule diff --git a/rtl/jt49/hdl/jt49_noise.v b/rtl/jt49/hdl/jt49_noise.v index 3ab3815..ffc1fb9 100644 --- a/rtl/jt49/hdl/jt49_noise.v +++ b/rtl/jt49/hdl/jt49_noise.v @@ -21,7 +21,6 @@ */ -`timescale 1ns / 1ps module jt49_noise( (* direct_enable *) input cen, diff --git a/rtl/jt49/hdl/jt49.qip b/rtl/jt49/syn/quartus/jt49.qip similarity index 66% rename from rtl/jt49/hdl/jt49.qip rename to rtl/jt49/syn/quartus/jt49.qip index 6568ae9..3715a5f 100644 --- a/rtl/jt49/hdl/jt49.qip +++ b/rtl/jt49/syn/quartus/jt49.qip @@ -1,7 +1,7 @@ -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_div.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_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 ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_bus.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_cen.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_exp.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ../../hdl/jt49_noise.v ] From 2bb576c37707c1b0ccccce50b798c6ccea83ae61 Mon Sep 17 00:00:00 2001 From: Cray Elliott Date: Sat, 24 Aug 2024 19:32:07 -0700 Subject: [PATCH 2/2] Adjust ADPCM-A channel volume to match real AES console recording (MDFourier) fixes #211 --- rtl/jt12/hdl/jt10_acc.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/jt12/hdl/jt10_acc.v b/rtl/jt12/hdl/jt10_acc.v index 14b5df3..f0756d7 100644 --- a/rtl/jt12/hdl/jt10_acc.v +++ b/rtl/jt12/hdl/jt10_acc.v @@ -80,8 +80,8 @@ reg acc_en_l, acc_en_r; always @(*) case( {cur_op,cur_ch} ) {2'd0,3'd0}: begin // ADPCM-A: - acc_input_l = (adpcmA_l <<< 2) + (adpcmA_l <<< 1); - acc_input_r = (adpcmA_r <<< 2) + (adpcmA_r <<< 1); + acc_input_l = (adpcmA_l <<< 2) + (adpcmA_l <<< 1) + adpcmA_l + (adpcmA_l >>> 2); // amplify by 7.25x to match AES channel balance + acc_input_r = (adpcmA_r <<< 2) + (adpcmA_r <<< 1) + adpcmA_r + (adpcmA_r >>> 2); `ifndef NOMIX acc_en_l = 1'b1; acc_en_r = 1'b1;