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

Subversion Repositories sqmusic

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/sqmusic/trunk/1942/1942.v
17,12 → 17,8
`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;
reg reset_n, clk, int_n, sound_clk;
 
initial begin
//$dumpfile("dump.lxt");
32,12 → 28,10
// $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;
//#4e6 $finish;
#5e9 $finish;
end
always begin // main clock
60,34 → 54,42
#(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) );
 
 
always #22676 $display("%d", amp0_y+amp1_y ); // 44.1kHz sample
wire [3:0] ay0_a, ay0_b, ay0_c, ay1_a, ay1_b, ay1_c;
computer_1942 #(0) game( .clk(clk), .sound_clk(sound_clk),
.int_n(int_n), .reset_n(reset_n),
.ay0_a(ay0_a), .ay0_b(ay0_b), .ay0_c(ay0_c),
.ay1_a(ay1_a), .ay1_b(ay1_b), .ay1_c(ay1_c) );
// sound amplifier:
wire [15:0] amp0_y, amp1_y;
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 ));
endmodule
 
/////////////////////////////////////////////////////
module MAP(
input [15:0] adr,
input [7:0] din,
output [7:0] dout,
module computer_1942
#(parameter dump_regs=0) // set to 1 to dump sqmusic registers
(
input clk,
input sound_clk,
input rd_n,
input wr_n,
input reset_n,
output bus_error );
input int_n,
output [3:0] ay0_a,
output [3:0] ay0_b,
output [3:0] ay0_c,
output [3:0] ay1_a,
output [3:0] ay1_b,
output [3:0] ay1_c
);
reg wait_n, nmi_n, busrq_n;
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;
 
wire [3:0] ay0_a, ay0_b, ay0_c, ay1_a, ay1_b, ay1_c;
wire [15:0] amp0_y, amp1_y;
100,13 → 102,25
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;
assign cpu_in=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 ),
initial begin
nmi_n=1;
wait_n=1;
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) );
 
RAM ram(.adr(adr[10:0]), .din(cpu_out), .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));
115,18 → 129,12
 
// 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),
AY_3_8910_capcom #(dump_regs,0) ay_0( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk),
.din(cpu_out), .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),
AY_3_8910_capcom #(dump_regs,1) ay_1( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk),
.din(cpu_out), .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
 
//////////////////////////////////////////////////////////
/sqmusic/trunk/1942/log2wav.cc
18,37 → 18,74
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <string>
 
using namespace std;
 
class Args {
public:
int skip;
string filename;
string outputfile;
Args( int argc, char *argv[]) : skip(0), outputfile("out.wav") {
int k=1;
bool filename_known=false;
while( k < argc ) {
if( strcmp(argv[k],"-l")==0 ) {
k++;
if( k >= argc ) throw "Expected number of lines to skip after -l";
skip = atoi( argv[k] );
cout << skip << " lines will be skipped\n";
k++;
continue;
}
if( strcmp(argv[k],"-o")==0 ) {
k++;
if( k >= argc ) throw "Expected output file name after -o";
outputfile = argv[k];
k++;
continue;
}
if( filename_known ) {
cout << "Unknown parameter " << argv[k] << "\n";
throw "Incorrect command line";
}
filename = argv[k];
filename_known = true;
k++;
}
if( filename=="-" ) filename=string("/dev/stdin");
}
};
 
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";
Args ar( argc, argv );
cout << "Input file " << ar.filename << "\n";
fin.open(ar.filename.c_str());
ofstream fout(ar.outputfile.c_str());
if( fin.bad() || fin.fail() ) throw "Cannot open input file";
if( fout.bad() || fout.fail() ) 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() ) {
// starts to come out
for( int k=0; k<ar.skip && !fin.eof(); k++ ) {
fin.getline( buffer, sizeof(buffer) );
if( strcmp(buffer,"ncsim> run" )==0) break;
//if( strcmp(buffer,"ncsim> run" )==0) break;
}
if( fin.eof() ) throw "Data not found";
fout.seekp(44);
while( !fin.eof() ) {
while( !fin.eof() && !fin.bad() && !fin.fail() ) {
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) );
/sqmusic/trunk/1942/readme
5,6 → 5,9
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
 
$ iverilog -s sound1942 -f gather -o sound1942 && vvp sound1942 > sim.log
 
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:
/sqmusic/trunk/sqm/sqm_pwm.v
0,0 → 1,158
/*
SQmusic
logarithmic PWM controller to use with SQMUSIC
Version 0.1, tested on simulation only with Capcom's 1942
 
(c) Jose Tejada Gomez, 11th 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_PWM(
input clk, // VHF clock (>33 MHz)
input reset_n,
input [3:0]A, input [3:0]B, input [3:0]C, // input channels
output Y
);
 
 
SQM_PWM_1 apwm( .clk(clk), .reset_n(reset_n), .din(A), .pwm(y_a) );
SQM_PWM_1 bpwm( .clk(clk), .reset_n(reset_n), .din(B), .pwm(y_b) );
SQM_PWM_1 cpwm( .clk(clk), .reset_n(reset_n), .din(C), .pwm(y_c) );
 
assign Y=y_a | y_b | y_c;
endmodule
 
////////////////////////////////////////////////////
// 1 channel only
module SQM_PWM_1(
input clk, // VHF clock (>33 MHz)
input reset_n,
input [3:0]din,
output reg pwm
);
 
reg [7:0] count, last0, last1;
wire [7:0]rep0, rep1;
 
SQM_PWM_LOG dec( .din(din), .rep0(rep0), .rep1(rep1), .zero(zero) );
 
always @(posedge clk or negedge reset_n) begin
if( !reset_n ) begin
count=0;
last0=0;
last1=1;
end
else
if( zero ) begin
pwm=0;
count=0;
end
else if( last0!=rep0 || last1!=rep1 ) begin
last0 <= rep0;
last1 <= rep1;
count = 0;
pwm=0;
end
else if( last0==1 && last1==1 ) begin
pwm=clk;
count=0;
end
else begin
if( pwm && count==last1-1 ) begin
count=0;
pwm=0;
end
else if( !pwm && count==last0-1 ) begin
count=0;
pwm=1;
end
else begin
count<=count+1;
pwm<=pwm;
end
end
end
endmodule
 
module SQM_PWM_LOG(
input [3:0]din,
output reg [7:0] rep0, // "L" repetition
output reg [7:0] rep1, // "H" repetition
output zero
);
 
assign zero = din==0;
 
always @(din)
case (din)
1: begin
rep0=64;
rep1=1;
end
2: begin
rep0=61;
rep1=1;
end
3: begin
rep0=32;
rep1=1;
end
4: begin
rep0=61;
rep1=2;
end
5: begin
rep0=16;
rep1=1;
end
6: begin
rep0=61;
rep1=4;
end
7: begin
rep0=8;
rep1=1;
end
8: begin
rep0=61;
rep1=8;
end
9: begin
rep0=61;
rep1=16;
end
10: begin
rep0=61;
rep1=8;
end
11: begin
rep0=2;
rep1=1;
end
12: begin
rep0=61;
rep1=32;
end
13: begin
rep0=1;
rep1=1;
end
14: begin
rep0=61;
rep1=64;
end
15: begin
rep0=1;
rep1=1;
end
default: begin
rep0=1;
rep1=1;
end
endcase
endmodule
/sqmusic/trunk/sqm/sqmusic.v
17,7 → 17,9
provides a 2-byte memory map as expected by Capcom games
*/
`timescale 1ns / 1ps
module AY_3_8910_capcom(
module AY_3_8910_capcom
#( parameter dump_writes=0, parameter id=0 )
(
input reset_n,
input clk, // CPU clock
input sound_clk, // normally slower than the CPU clock
57,17 → 59,19
end
end
 
SQMUSIC core( .reset_n(reset_n), .clk(sound_clk), .data_in(latches[1]),
SQMUSIC #(dump_writes, id) 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
module SQMUSIC
#( parameter dump_writes=0, parameter id=0 ) // set to 1 to dump register writes
( // note that input ports are not multiplexed
input reset_n,
input clk,
input [7:0] data_in,
output reg [7:0] data_out, // read functionality not implemented yet
output reg [7:0] data_out,
input [3:0] adr,
input rd, // read
input wr, // write
124,7 → 128,12
else begin
if( rd )
data_out=regarray[ adr ];
else if( wr ) regarray[adr]=data_in;
else if( wr ) begin
regarray[adr]=data_in;
if( dump_writes ) begin
$display("#%d, %t, %d, %d", id, $realtime, adr, data_in );
end
end
end
end
 
/sqmusic/trunk/sqm/sqm_pwm_1_tb.v
0,0 → 1,44
/*
SQmusic
logarithmic PWM controller to use with SQMUSIC
Version 0.1, tested on simulation only with Capcom's 1942
 
(c) Jose Tejada Gomez, 11th 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:
// iverilog sqm_pwm_1_tb.v sqm_pwm.v -s sqm_pwm_1_tb -o sqm_pwm_1_tb
 
`timescale 1ns/1ps
module sqm_pwm_1_tb;
 
reg clk;
always begin
clk=0;
#10 clk <= ~clk;
end
 
reg [3:0]A;
always begin
A=0;
#5000 A <= A+1;
end
 
reg reset_n;
initial begin
$dumpvars();
$dumpon;
reset_n=0;
#15 reset_n=1;
#80000 $finish;
end
 
SQM_PWM_1 apwm( .clk(clk), .reset_n(reset_n), .din(A), .pwm(y_a) );
 
endmodule

powered by: WebSVN 2.1.0

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