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 5 to Rev 6
    Reverse comparison

Rev 5 → Rev 6

/sqmusic/trunk/1942/computer_1942.v
0,0 → 1,183
/*
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
 
*/
 
module computer_1942
#(parameter dump_regs=0) // set to 1 to dump sqmusic registers
(
input clk,
input sound_clk,
input reset_n,
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 [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 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);
*/
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));
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 #(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 #(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) );
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
19,6 → 19,7
module sound1942;
// inputs to Z80
reg reset_n, clk, int_n, sound_clk;
parameter dump_text = 1; // set to 1 to dump data to use log2wav later
 
initial begin
/* $dumpfile("dump.lxt");
27,12 → 28,13
// $dumpvars();
// $dumpon;
// $shm_open("1942.shm");
// $shm_probe( sound1942, "ACTFS" );
// $shm_probe( sound1942, "ACTFS" );
reset_n=0;
#1500 reset_n=1;
$display("1942 START");
// change finish time depending on song
//#4e6 $finish;
#6e9 $finish;
//#0.1e9 $finish;
#7e9 $finish;
end
always begin // main clock
73,7 → 75,7
always begin
vhf_clk=0;
forever begin
if( vhf_clk ) begin
if( vhf_clk && dump_text ) begin
$display("%d, %d, %d, %d, %d, %d",
pwm0_a, pwm0_b, pwm0_c, pwm1_a, pwm1_b, pwm1_c );
end
88,176 → 90,6
SQM_PWM_1 a1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_a), .pwm(pwm1_a) );
SQM_PWM_1 b1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_b), .pwm(pwm1_b) );
SQM_PWM_1 c1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_c), .pwm(pwm1_c) );
endmodule
 
/////////////////////////////////////////////////////
module computer_1942
#(parameter dump_regs=0) // set to 1 to dump sqmusic registers
(
input clk,
input sound_clk,
input reset_n,
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;
 
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 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);
*/
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));
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 #(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 #(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) );
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/log2wav.cc
20,6 → 20,7
#include <assert.h>
#include <string.h>
#include <string>
#include <signal.h>
 
using namespace std;
 
65,6 → 66,12
}
};
 
bool sigint_abort=false;
 
void sigint_handle(int x ) {
sigint_abort = true;
}
 
int main(int argc, char *argv[]) {
try {
ifstream fin;
81,7 → 88,7
// 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
// 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;
88,7 → 95,9
}
if( fin.eof() ) throw "Data not found";
fout.seekp(44);
while( !fin.eof() && !fin.bad() && !fin.fail() ) {
signal( 2, sigint_handle ); // capture CTRL+C in order to save the
// WAV header before quiting
while( !fin.eof() && !fin.bad() && !fin.fail() && !sigint_abort ) {
short int value;
fin.getline( buffer, sizeof(buffer) );
/sqmusic/trunk/1942/gather
1,4 → 1,5
1942.v
computer_1942.v
../tv80/rtl/core/tv80n.v
../tv80/rtl/core/tv80_core.v
../tv80/rtl/core/tv80_alu.v
/sqmusic/trunk/1942/pwm2log.cc
54,7 → 54,9
try {
long int sample=0;
// skip first line
cin.getline( buf, sizeof(buf) );
buf[0]=0;
while( strncmp("1942 START",buf, 11 ) && !cin.eof() && !cin.fail() )
cin.getline( buf, sizeof(buf) );
cin.getline( buf, sizeof(buf) );
while( buf[0] && !cin.eof() ) {
/sqmusic/trunk/sqm/sqm_pwm.v
43,37 → 43,37
 
always @(posedge clk or negedge reset_n) begin
if( !reset_n ) begin
count=0;
last0=0;
last1=1;
count<=0;
last0<=0;
last1<=1;
end
else
if( zero ) begin
pwm=0;
count=0;
pwm <=0;
count<=0;
end
else if( last0!=rep0 || last1!=rep1 ) begin
last0 <= rep0;
last1 <= rep1;
count = 0;
pwm=0;
count <= 0;
pwm <=0;
end
else if( last0==1 && last1==1 ) begin
pwm=clk;
count=0;
pwm <=clk;
count<=0;
end
else begin
if( pwm && count==last1-1 ) begin
count=0;
pwm=0;
count<=0;
pwm <=0;
end
else if( !pwm && count==last0-1 ) begin
count=0;
pwm=1;
count<=0;
pwm <=1;
end
else begin
count<=count+1;
pwm<=pwm;
pwm <=pwm;
end
end
end
/sqmusic/trunk/sqm/ay_3_8910_capcom_tb.v
0,0 → 1,75
`timescale 1ns / 1ps
module ay_3_8910_capcom_tb;
 
reg reset_n, clk, int_n, sound_clk;
reg [7:0] data;
reg wr_n, cs_n, adr;
parameter dump_text = 1; // set to 1 to dump data to use log2wav later
 
initial begin
/* $dumpfile("dump.lxt");
$dumpvars(1,pwm0);
$dumpvars(1,pwm1);*/
// $dumpvars();
// $dumpon;
$shm_open( "ay_3_8910_capcom_tb.shm");
$shm_probe( ay_3_8910_capcom_tb, "ACTFS" );
reset_n=0;
data=0;
wr_n=1;
cs_n=1;
adr=0;
#1500 reset_n=1;
// write 201 to register 15
adr=0;
data=8'h3F;
wr_n=0;
cs_n=0;
#668
data=201;
adr=1;
#668
// write 134 to register 4
#668
adr=0;
data=8'h04;
wr_n=0;
cs_n=0;
#668
data=134;
adr=1;
#668
// write 63 to register 12
#668
adr=0;
data=12;
wr_n=0;
cs_n=0;
#668
data= 63;
adr=1;
#668
wr_n=1;
data=0;
#700
$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
 
 
AY_3_8910_capcom #(1,0) ay( .reset_n(reset_n), .clk(clk), // CPU clock
.sound_clk(sound_clk), // normally slower than the CPU clock
.din(data), .adr(adr), .wr_n(wr_n), .cs_n(cs_n), // chip select
.A(A),.B(B),.C(C) // channel outputs
);
 
endmodule
/sqmusic/trunk/sqm/sqmusic.v
30,39 → 30,24
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 [3:0] adr_latch;
wire sample = ~cs_n & ~wr_n;
wire core_wr = adr & sample;
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
always @(posedge clk or negedge reset_n) begin
if(!reset_n)
adr_latch <= 0;
else
if( sample && adr==0 )
adr_latch <= din[3:0];
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 #(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) );
SQMUSIC #(dump_writes, id) core( .reset_n(reset_n), .clk(sound_clk), .data_in(din),
.adr( adr_latch ), .rd(1'b0), .wr(core_wr), .A(A), .B(B), .C(C) );
endmodule
 
//////////////////////////////////////////////////////////////////////////////
/* The AY core does
*/
module SQMUSIC
110,17 → 95,16
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
always @(posedge clk or negedge reset_n) begin
if( !reset_n)
clkdiv16=0;
clkdiv16<=0;
else
clkdiv16<=clkdiv16+1;
end
 
always @(posedge clk or reset_n) begin
integer aux;
always @(posedge clk or negedge reset_n) begin
if( !reset_n ) begin
data_out=0;
for(aux=0;aux<=15;aux=aux+1) regarray[aux]=0;
159,10 → 143,10
 
assign div = period==1 ? clk : clkdiv;
 
always @(posedge clk or reset_n) begin
always @(posedge clk or negedge reset_n) begin
if( !reset_n) begin
count=0;
clkdiv=0;
count<=0;
clkdiv<=0;
end
else begin
if( period==0 ) begin
171,7 → 155,7
end
else if( count >= period ) begin
count <= 0;
clkdiv = ~clkdiv;
clkdiv <= ~clkdiv;
end
else count <= count+1;
end
192,12 → 176,12
assign noise=poly17[16];
wire noise_clk;
 
always @(posedge noise_clk or reset_n) begin
always @(posedge noise_clk or negedge reset_n) begin
if( !reset_n) begin
poly17=0;
poly17<=0;
end
else begin
poly17={ poly17[0] ^ poly17[2] ^ poly17_zero, poly17[16:1] };
poly17<={ poly17[0] ^ poly17[2] ^ poly17_zero, poly17[16:1] };
end
end
 
217,12 → 201,12
reg stop;
reg [3:0]prev_ctrl; // last control orders
 
always @(posedge clk or reset_n) begin
always @(posedge clk or negedge reset_n) begin
if( !reset_n) begin
gain=4'hF;
dir=0;
prev_ctrl=0;
stop=1;
gain<=4'hF;
dir<=0;
prev_ctrl<=0;
stop<=1;
end
else begin
if (ctrl!=prev_ctrl) begin

powered by: WebSVN 2.1.0

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