URL
https://opencores.org/ocsvn/sqmusic/sqmusic/trunk
Subversion Repositories sqmusic
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/sqmusic/trunk/1942/1942.v
0,0 → 1,233
/* |
1942 simple board setup in order to test SQMUSIC. |
|
Requirements: |
TV80, Z80 Verilog module |
Dump of Z80 ROM from 1942 board |
|
(c) Jose Tejada Gomez, 9th May 2013 |
You can use this file following the GNU GENERAL PUBLIC LICENSE version 3 |
Read the details of the license in: |
http://www.gnu.org/licenses/gpl.txt |
|
Send comments to: jose.tejada@ieee.org |
|
*/ |
|
`timescale 1ns / 1ps |
|
module sound1942; |
wire [7:0]cpu_in, cpu_out; |
wire [15:0]adr; |
wire m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n; |
wire bus_error; |
// inputs to Z80 |
reg reset_n, clk, wait_n, int_n, nmi_n, busrq_n, sound_clk; |
|
initial begin |
//$dumpfile("dump.lxt"); |
//$dumpvars(1,map.ym2203_0); |
// $dumpvars(); |
// $dumpon; |
// $shm_open("1942.shm"); |
// $shm_probe( sound1942, "ACTFS" ); |
reset_n=0; |
nmi_n=1; |
wait_n=1; |
#1500 reset_n=1; |
// change finish time depending on song |
// #400e6 $finish; |
#10e9 $finish; |
end |
|
always begin // main clock |
clk=0; |
forever clk = #167 ~clk; |
end |
|
always begin // sound clock |
sound_clk=0; |
forever sound_clk = #334 ~sound_clk; |
end |
|
parameter int_low_time=167*2*80; |
|
always begin // interrupt clock |
int_n=1; |
forever begin |
#(4166667-int_low_time) int_n=0; // 240Hz |
//$display("IRQ request @ %t us",$time/1e6); |
#(int_low_time) int_n=1; |
end |
end |
|
|
tv80n cpu( //outputs |
.m1_n(m1_n), .mreq_n(mreq_n), .iorq_n(iorq_n), .rd_n(rd_n), .wr_n(wr_n), |
.rfsh_n(rfsh_n), .halt_n(halt_n), .busak_n(busak_n), .A(adr), .do(cpu_out), |
// Inputs |
.reset_n(reset_n), .clk(clk), .wait_n(wait_n), |
.int_n(int_n), .nmi_n(nmi_n), .busrq_n(busrq_n), .di(cpu_in) ); |
|
MAP map( .adr(adr), .din(cpu_out), .dout(cpu_in), .clk(clk), |
.sound_clk( sound_clk ), .wr_n(wr_n), .rd_n(rd_n), |
.bus_error(bus_error), .reset_n(reset_n) ); |
|
|
|
endmodule |
|
///////////////////////////////////////////////////// |
module MAP( |
input [15:0] adr, |
input [7:0] din, |
output [7:0] dout, |
input clk, |
input sound_clk, |
input rd_n, |
input wr_n, |
input reset_n, |
output bus_error ); |
|
wire [3:0] ay0_a, ay0_b, ay0_c, ay1_a, ay1_b, ay1_c; |
wire [15:0] amp0_y, amp1_y; |
|
wire [7:0]ram_out, rom_out, latch_out; |
wire rom_enable = adr<16'h4000 ? 1:0; |
wire ram_enable = adr>=16'h4000 && adr<16'h4800 ? 1:0; |
wire latch_enable = adr==16'h6000 ? 1 : 0; |
wire ay_0_enable = adr==16'h8000 || adr==16'h8001 ? 1:0; |
wire ay_1_enable = adr==16'hC000 || adr==16'hC001 ? 1:0; |
assign bus_error = ~ram_enable & ~rom_enable & ~latch_enable & |
~ay_0_enable & ~ay_1_enable; |
assign dout=ram_out | rom_out | latch_out; |
/* |
always @(negedge rd_n) |
if( !rd_n && adr==8'h38 ) |
$display("IRQ processing started @ %t us",$time/1e6); |
*/ |
RAM ram(.adr(adr[10:0]), .din(din), .dout(ram_out), .enable( ram_enable ), |
.clk(clk), .wr_n(wr_n), .rd_n(rd_n) ); |
ROM rom(.adr(adr[13:0]), .data(rom_out), .enable(rom_enable), |
.rd_n(rd_n), .clk(clk)); |
SOUND_LATCH sound_latch( .dout(latch_out), .enable(latch_enable), |
.clk(clk), .rd_n(rd_n) ); |
|
// fake_ay ay_0( .adr(adr[0]), .din(din), .clk(clk), .wr_n(~ay_0_enable|wr_n) ); |
|
AY_3_8910_capcom ay_0( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk), |
.din(din), .adr(adr[0]), .wr_n(wr_n), .cs_n(~ay_0_enable), |
.A(ay0_a), .B(ay0_b), .C(ay0_c) ); |
AY_3_8910_capcom ay_1( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk), |
.din(din), .adr(adr[0]), .wr_n(wr_n), .cs_n(~ay_1_enable), |
.A(ay1_a), .B(ay1_b), .C(ay1_c) ); |
|
SQM_AMP amp0( .A(ay0_a), .B(ay0_b), .C(ay0_c), .Y( amp0_y )); |
SQM_AMP amp1( .A(ay1_a), .B(ay1_b), .C(ay1_c), .Y( amp1_y )); |
|
always #22676 $display("%d", amp0_y+amp1_y ); // 44.1kHz sample |
// initial $dumpvars(0,ym2203_0); |
endmodule |
|
////////////////////////////////////////////////////////// |
// this module is used to check the communication of the |
// Z80 with the AY-3-8910 |
// only used for debugging |
module fake_ay( |
input adr, |
input [7:0] din, |
input clk, |
input wr_n ); |
|
reg [7:0] contents[1:0]; |
wire sample = clk & ~wr_n; |
|
always @(posedge sample) begin |
// if( contents[adr] != din ) begin |
$display("%t -> %d = %d", $realtime/1e6, adr, din ); |
if( !adr && din>15 ) $display("AY WARNING"); |
contents[adr] = din; |
end |
|
endmodule |
|
////////////////////////////////////////////////////////// |
module RAM( |
input [10:0] adr, |
input [7:0] din, |
output reg [7:0] dout, |
input enable, |
input clk, |
input rd_n, |
input wr_n ); |
|
reg [7:0] contents[2047:0]; |
wire sample = clk & (~rd_n | ~wr_n ); |
|
initial dout=0; |
|
always @(posedge sample) begin |
if( !enable ) |
dout=0; |
else begin |
if( !wr_n ) contents[adr]=din; |
if( !rd_n ) dout=contents[adr]; |
end |
end |
endmodule |
|
////////////////////////////////////////////////////////// |
module ROM( |
input [13:0] adr, |
output reg [7:0] data, |
input enable, |
input rd_n, |
input clk ); |
|
reg [7:0] contents[16383:0]; |
|
wire sample = clk & ~rd_n; |
|
initial begin |
$readmemh("../rom/sr-01.c11.hex", contents ); // this is the hex dump of the ROM |
data=0; |
end |
|
always @( posedge sample ) begin |
if ( !enable ) |
data=0; |
else |
data=contents[ adr ]; |
end |
endmodule |
|
////////////////////////////////////////////////////////// |
module SOUND_LATCH( |
output reg [7:0] dout, |
input enable, |
input clk, |
input rd_n ); |
|
wire sample = clk & ~rd_n; |
reg [7:0]data; |
|
initial begin |
dout=0; |
data=0; |
#100e6 data=8'h12; // enter the song/sound code here |
end |
|
always @(posedge sample) begin |
if( !enable ) |
dout=0; |
else begin |
if( !rd_n ) begin |
// $display("Audio latch read @ %t us", $realtime/1e6 ); |
// if( data != 0 ) |
// $display("Audio latch read (%X) @ %t us", data, $realtime/1e6 ); |
dout=data; |
end |
end |
end |
endmodule |
|
sqmusic/trunk/1942/1942.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sqmusic/trunk/1942/log2wav.cc
===================================================================
--- sqmusic/trunk/1942/log2wav.cc (nonexistent)
+++ sqmusic/trunk/1942/log2wav.cc (revision 3)
@@ -0,0 +1,91 @@
+/*
+ Converts output from 1942.v to .wav file
+
+ (c) Jose Tejada Gomez, 9th May 2013
+ You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
+ Read the details of the license in:
+ http://www.gnu.org/licenses/gpl.txt
+
+ Send comments to: jose.tejada@ieee.org
+
+*/
+
+// Compile with g++ log2wav.cc -o log2wav
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+int main(int argc, char *argv[]) {
+ try {
+ ifstream fin;
+ if( argc == 2)
+ fin.open(argv[1]);
+ else
+ fin.open("/dev/stdin");
+ ofstream fout("out.wav");
+ if( fin.bad() ) throw "Cannot open input file";
+ if( fout.bad() ) throw "Cannot open output file";
+ assert( sizeof(short int)==2 );
+ char buffer[1024];
+ int data=0;
+
+ // depending on the simulator the following "while"
+ // section might no be needed or modified
+ // It just skips simulator output until the real data
+ // starts to come out
+ while( !fin.eof() ) {
+ fin.getline( buffer, sizeof(buffer) );
+ if( strcmp(buffer,"ncsim> run" )==0) break;
+ }
+
+ if( fin.eof() ) throw "Data not found";
+ fout.seekp(44);
+ while( !fin.eof() ) {
+ short int value;
+ fin.getline( buffer, sizeof(buffer) );
+ if( buffer[0]=='S' ) break; // reached line "Simulation complete"
+ value = atoi( buffer );
+ fout.write( (char*) &value, sizeof(value) );
+ data++;
+ }
+ cout << data << " samples written\n";
+ // Write the header
+ const char *RIFF = "RIFF";
+ fout.seekp(0);
+ fout.write( RIFF, 4 );
+ int aux=36+2*data;
+ fout.write( (char*)&aux, 4 );
+ const char *WAVE = "WAVE";
+ fout.write( WAVE, 4 );
+ const char *fmt = "fmt ";
+ fout.write( fmt, 4 );
+ aux=16;
+ fout.write( (char*)&aux, 4 );// suubchunk 1 size
+ short int aux_short = 1;
+ fout.write( (char*)&aux_short, 2 ); // audio format (1)
+ fout.write( (char*)&aux_short, 2 ); // num channels (1)
+ aux=44100;
+ fout.write( (char*)&aux, 4 );
+ aux=44100*1*2;
+ fout.write( (char*)&aux, 4 ); // byte rate
+ aux_short=2;
+ fout.write( (char*)&aux_short, 2 ); // block align
+ aux_short=16;
+ fout.write( (char*)&aux_short, 2 ); // bits per sample
+ RIFF="data";
+ fout.write( RIFF, 4 );
+ aux = data*2;
+ fout.write( (char*)&aux, 4 ); // data size
+ return 0;
+ }
+ catch( const char *msg ) {
+ cout << msg << "\n";
+ return -1;
+ }
+}
sqmusic/trunk/1942/log2wav.cc
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sqmusic/trunk/1942/dump.cc
===================================================================
--- sqmusic/trunk/1942/dump.cc (nonexistent)
+++ sqmusic/trunk/1942/dump.cc (revision 3)
@@ -0,0 +1,53 @@
+/*
+ Converts binary ROM dump to hexadecimal format
+ so Verilog can read it
+
+ Requirements:
+ TV80, Z80 Verilog module
+ Dump of Z80 ROM from 1942 board
+
+ (c) Jose Tejada Gomez, 9th May 2013
+ You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
+ Read the details of the license in:
+ http://www.gnu.org/licenses/gpl.txt
+
+ Send comments to: jose.tejada@ieee.org
+
+*/
+
+// Compile with: g++ dump.cc -o dump
+
+#include
+#include
+
+using namespace std;
+
+int main( int argc, char *argv[]) {
+ if( argc!=2 ) {
+ cout << "Usage: dump filename\n";
+ return -1;
+ }
+ ifstream f( argv[1] );
+ unsigned char *buffer = new unsigned char[16*1024];
+ f.read( (char*)buffer, 16*1024 );
+ cout << hex;
+ unsigned char *aux=buffer;
+ // swap all bytes
+ /*
+ for(int k=0;k<32*1024; k+=2) {
+ unsigned char*p = aux;
+ unsigned char x0 = *aux++;
+ unsigned char x1 = *aux;
+ *p=x1;
+ *aux=x0;
+ aux=p+2;
+ }
+ aux=buffer;*/
+ for(int k=0; k<16*1024; k++ ) {
+ unsigned val = *aux++;
+ cout << val << "\n";
+ }
+
+ delete [] buffer;
+ return 0;
+}
sqmusic/trunk/1942/dump.cc
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sqmusic/trunk/1942/gather
===================================================================
--- sqmusic/trunk/1942/gather (nonexistent)
+++ sqmusic/trunk/1942/gather (revision 3)
@@ -0,0 +1,8 @@
+1942.v
+../tv80/rtl/core/tv80n.v
+../tv80/rtl/core/tv80_core.v
+../tv80/rtl/core/tv80_alu.v
+../tv80/rtl/core/tv80_mcode.v
+../tv80/rtl/core/tv80_reg.v
+../sqm/sqm_amp.v
+../sqm/sqmusic.v
sqmusic/trunk/1942/gather
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sqmusic/trunk/1942/readme
===================================================================
--- sqmusic/trunk/1942/readme (nonexistent)
+++ sqmusic/trunk/1942/readme (revision 3)
@@ -0,0 +1,14 @@
+Instructions to play Capcom's 1942 music with a Verilog simulator:
+
+
+1. Dump rom sr-01.c11 from Capcom's 1942 arcade board
+2. Compile and run "dump.cc" program to convert the binary file to hexadecimal format
+3. Place file in ../rom folder (see 1942.v file for details on location)
+4. Run verilog simulation from 1942 folder using the "gather" file
+5. Pass the output of the simulation through "log2wav.cc", either using a pipe or storing it on a file. Check that the data dump is caught correctly by log2wav as some simulators will add extra information at the beginning of the file
+
+Other:
+
+-tv80 project files are expected to be in ../tv80
+-the music code played can be changed in 1942.v
+-you may need to adjust the length of the simulation to listen the full song
Index: sqmusic/trunk/sqm/sqm_amp.v
===================================================================
--- sqmusic/trunk/sqm/sqm_amp.v (nonexistent)
+++ sqmusic/trunk/sqm/sqm_amp.v (revision 3)
@@ -0,0 +1,53 @@
+/*
+ SQmusic
+ logarithmic digital amplifier to use with SQMUSIC
+ Version 0.1, tested on simulation only with Capcom's 1942
+
+ (c) Jose Tejada Gomez, 9th May 2013
+ You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
+ Read the details of the license in:
+ http://www.gnu.org/licenses/gpl.txt
+
+ Send comments to: jose.tejada@ieee.org
+
+*/
+`timescale 1ns / 1ps
+module SQM_AMP(
+ input [3:0]A, input [3:0]B, input [3:0]C, // input channels
+ output [15:0] Y
+);
+
+wire[11:0] Alog, Blog, Clog;
+
+SQM_LOG adac( .din(A), .dout(Alog) );
+SQM_LOG bdac( .din(B), .dout(Blog) );
+SQM_LOG cdac( .din(C), .dout(Clog) );
+//always @(*)
+assign Y=Alog+Blog+Clog;
+endmodule
+
+module SQM_LOG(
+ input [3:0]din,
+ output reg [11:0]dout );
+
+always @(din)
+ case (din)
+ 0: dout=0;
+ 1: dout=16;
+ 2: dout=19;
+ 3: dout=32;
+ 4: dout=39;
+ 5: dout=64;
+ 6: dout=78;
+ 7: dout=128;
+ 8: dout=155;
+ 9: dout=256;
+ 10: dout=310;
+ 11: dout=512;
+ 12: dout=621;
+ 13: dout=1024;
+ 14: dout=1448;
+ 15: dout=2048;
+ endcase
+
+endmodule
sqmusic/trunk/sqm/sqm_amp.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sqmusic/trunk/sqm/sqmusic.v
===================================================================
--- sqmusic/trunk/sqm/sqmusic.v (nonexistent)
+++ sqmusic/trunk/sqm/sqmusic.v (revision 3)
@@ -0,0 +1,254 @@
+/*
+ SQmusic
+ Music synthetiser compatible with AY-3-8910 software compatible
+ Version 0.1, tested on simulation only with Capcom's 1942
+
+ (c) Jose Tejada Gomez, 9th May 2013
+ You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
+ Read the details of the license in:
+ http://www.gnu.org/licenses/gpl.txt
+
+ Send comments to: jose.tejada@ieee.org
+
+*/
+
+/* Capcom arcade boards like 1942 use two memory locations to
+communicate with the AY-3-8910 (or compatible) chip. This small code
+provides a 2-byte memory map as expected by Capcom games
+*/
+`timescale 1ns / 1ps
+module AY_3_8910_capcom(
+ input reset_n,
+ input clk, // CPU clock
+ input sound_clk, // normally slower than the CPU clock
+ input [7:0] din,
+ input adr,
+ input wr_n, // write
+ input cs_n, // chip select
+ output [3:0]A,B,C // channel outputs
+);
+
+reg [7:0] latches[1:0];
+reg core_wr;
+wire sample = clk & ~cs_n & ~wr_n;
+reg count;
+
+always @(posedge sound_clk or negedge reset_n) begin
+ if(!reset_n) begin
+ count=0;
+ end
+ else begin
+ if( !count && core_wr) count=1;
+ else if( core_wr ) begin
+ count=0;
+ core_wr=0;
+ end
+ end
+end
+
+always @(posedge sample or negedge reset_n) begin
+ if(!reset_n) begin
+ latches[0]=0;
+ latches[1]=0;
+ end
+ else begin
+ latches[adr] = din;
+ if(adr) core_wr=1;
+ end
+end
+
+SQMUSIC core( .reset_n(reset_n), .clk(sound_clk), .data_in(latches[1]),
+ .adr( latches[0][3:0] ), .rd(1'b0), .wr(core_wr), .A(A), .B(B), .C(C) );
+endmodule
+
+/* The AY core does
+*/
+module SQMUSIC( // pins are not multiplexed
+ input reset_n,
+ input clk,
+ input [7:0] data_in,
+ output reg [7:0] data_out, // read functionality not implemented yet
+ input [3:0] adr,
+ input rd, // read
+ input wr, // write
+ output [3:0]A,B,C // channel outputs
+);
+
+reg [7:0] regarray[15:0];
+reg [3:0] clkdiv16;
+
+wire [3:0] envelope;
+wire [2:0] sqwave;
+wire noise, envclk;
+wire Amix = (noise|regarray[7][3]) ^ (sqwave[0]|regarray[7][0]);
+wire Bmix = (noise|regarray[7][4]) ^ (sqwave[1]|regarray[7][1]);
+wire Cmix = (noise|regarray[7][5]) ^ (sqwave[2]|regarray[7][2]);
+
+// internal modules operate at clk/16
+SQM_CLK_DIVIDER #(12) chA( .clk(clkdiv16[3]), .reset_n(reset_n),
+ .period({regarray[1][3:0], regarray[0][7:0] }), .div(sqwave[0]) );
+SQM_CLK_DIVIDER #(12) chB( .clk(clkdiv16[3]), .reset_n(reset_n),
+ .period({regarray[3][3:0], regarray[2][7:0] }), .div(sqwave[1]) );
+SQM_CLK_DIVIDER #(12) chC( .clk(clkdiv16[3]), .reset_n(reset_n),
+ .period({regarray[5][3:0], regarray[4][7:0] }), .div(sqwave[2]) );
+
+// the noise uses a x2 faster clock in order to produce a frequency
+// of Fclk/16 when period is 1
+SQM_NOISE ng( .clk(clkdiv16[3]), .reset_n(reset_n),
+ .period(regarray[6][4:0]), .noise(noise) );
+// envelope generator
+SQM_CLK_DIVIDER #(16) envclkdiv( .clk(clkdiv16[2]), .reset_n(reset_n),
+ .period({regarray[14],regarray[13]}), .div(envclk) );
+SQM_ENVELOPE env( .clk(envclk),.ctrl(regarray[15][3:0]),
+ .gain(envelope), .reset_n(reset_n) );
+
+assign A=regarray[10][4]? envelope&{4{Amix}} : regarray[10][3:0]&{4{Amix}};
+assign B=regarray[11][4]? envelope&{4{Bmix}} : regarray[10][3:0]&{4{Bmix}};
+assign C=regarray[12][4]? envelope&{4{Cmix}} : regarray[10][3:0]&{4{Cmix}};
+
+integer aux;
+
+// 16-count divider
+always @(posedge clk or reset_n) begin
+ if( !reset_n)
+ clkdiv16=0;
+ else
+ clkdiv16<=clkdiv16+1;
+end
+
+always @(posedge clk or reset_n) begin
+ if( !reset_n ) begin
+ data_out=0;
+ for(aux=0;aux<=15;aux=aux+1) regarray[aux]=0;
+ end
+ else begin
+ if( rd )
+ data_out=regarray[ adr ];
+ else if( wr ) regarray[adr]=data_in;
+ end
+end
+
+endmodule
+
+module SQM_CLK_DIVIDER(
+ clk, // this is the divided down clock from the core
+ reset_n,
+ period,
+ div
+);
+
+parameter bw=12;
+input clk; // this is the divided down clock from the core
+input reset_n;
+input [bw-1:0]period;
+output div;
+
+reg [bw-1:0]count;
+reg clkdiv;
+
+initial clkdiv=0;
+
+assign div = period==1 ? clk : clkdiv;
+
+always @(posedge clk or reset_n) begin
+ if( !reset_n) begin
+ count=0;
+ clkdiv=0;
+ end
+ else begin
+ if( period==0 ) begin
+ clkdiv<=0;
+ count<=0;
+ end
+ else if( count >= period ) begin
+ count <= 0;
+ clkdiv = ~clkdiv;
+ end
+ else count <= count+1;
+ end
+end
+endmodule
+
+////////////////////////////////////////////////////////////////
+module SQM_NOISE(
+ input clk, // this is the divided down clock from the core
+ input reset_n,
+ input [4:0]period,
+ output noise
+);
+
+reg [5:0]count;
+reg [16:0]poly17;
+wire poly17_zero = poly17==0;
+assign noise=poly17[16];
+wire noise_clk;
+
+always @(posedge noise_clk or reset_n) begin
+ if( !reset_n) begin
+ poly17=0;
+ end
+ else begin
+ poly17={ poly17[0] ^ poly17[2] ^ poly17_zero, poly17[16:1] };
+ end
+end
+
+SQM_CLK_DIVIDER #(5) ndiv( .clk(clk), .reset_n(reset_n),
+ .period(period), .div(noise_clk) );
+endmodule
+
+////////////////////////////////////////////////////////////////
+module SQM_ENVELOPE(
+ input clk, // this is the divided down clock from the core
+ input reset_n,
+ input [3:0]ctrl,
+ output reg [3:0]gain
+);
+
+reg dir; // direction
+reg stop;
+reg [3:0]prev_ctrl; // last control orders
+
+always @(posedge clk or reset_n) begin
+ if( !reset_n) begin
+ gain=4'hF;
+ dir=0;
+ prev_ctrl=0;
+ stop=1;
+ end
+ else begin
+ if (ctrl!=prev_ctrl) begin
+ prev_ctrl<=ctrl;
+ if( ctrl[2] ) begin
+ gain<=0;
+ dir<=1;
+ stop<=0;
+ end
+ else begin
+ gain<=4'hF;
+ dir<=0;
+ stop<=0;
+ end
+ end
+ else begin
+ if (!stop) begin
+ if( !prev_ctrl[3] && ((gain==0&&!dir) || (gain==4'hF&&dir))) begin
+ stop<=1;
+ gain<=0;
+ end
+ else begin
+ if( prev_ctrl[0] && ( (gain==0&&!dir) || (gain==4'hF&&dir))) begin // HOLD
+ stop<=1;
+ gain <= prev_ctrl[1]? ~gain : gain;
+ end
+ else begin
+ gain <= dir ? gain+1 : gain-1;
+ if( prev_ctrl[1:0]==2'b10 && ( (gain==1&&!dir) || (gain==4'hE&&dir))) begin // ALTERNATE
+ dir <= ~dir;
+ end
+ end
+ end
+ end
+ end
+ end
+end
+endmodule
sqmusic/trunk/sqm/sqmusic.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property