mirror of https://github.com/zxdos/zxuno.git
SamCoupe a test3
This commit is contained in:
parent
9b683eb5f6
commit
e6c3fca97a
|
|
@ -67,12 +67,12 @@ module asic (
|
|||
HBPORCH = 64,
|
||||
LBORDER = 48;
|
||||
|
||||
parameter HTOTAL = HACTIVEREGION +
|
||||
RBORDER +
|
||||
parameter HTOTAL = RBORDER +
|
||||
HFPORCH +
|
||||
HSYNC +
|
||||
HBPORCH +
|
||||
LBORDER;
|
||||
LBORDER +
|
||||
HACTIVEREGION;
|
||||
|
||||
parameter VACTIVEREGION = 192,
|
||||
BBORDER = 48,
|
||||
|
|
@ -89,19 +89,11 @@ module asic (
|
|||
TBORDER;
|
||||
|
||||
// Start of vertical sync, horizontal counter (last 4 scanlines)
|
||||
parameter BEGINVSYNCH = HACTIVEREGION + RBORDER + HFPORCH + HSYNC + HBPORCH;
|
||||
parameter BEGINVSYNCH = 0;
|
||||
|
||||
// Start and end of vertical retrace interrupt, horizontal counter
|
||||
parameter BEGINVINTH = BEGINVSYNCH; //HACTIVEREGION + RBORDER + HFPORCH;
|
||||
parameter ENDVINTH = (BEGINVINTH + 256)%HTOTAL;
|
||||
|
||||
// Start and end of vertical retrace interrupt, vertical counter
|
||||
parameter BEGINVINTV = VACTIVEREGION + BBORDER + VFPORCH - 1;
|
||||
parameter ENDVINTV = VACTIVEREGION + BBORDER + VFPORCH;
|
||||
|
||||
// Start and end of raster interrupt, horizontal counter
|
||||
parameter BEGINHINTH = HACTIVEREGION + RBORDER;
|
||||
parameter ENDHINTH = (BEGINHINTH + 256)%HTOTAL;
|
||||
// Start and end of vertical sync
|
||||
parameter BEGINVSYNCV = VACTIVEREGION + BBORDER + VFPORCH;
|
||||
parameter ENDVSYNCV = BEGINVSYNCV + 4;
|
||||
|
||||
parameter IOADDR_VMPR = 8'd252,
|
||||
IOADDR_HMPR = 8'd251,
|
||||
|
|
@ -115,12 +107,7 @@ module asic (
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IO regs
|
||||
`ifdef SYNTH
|
||||
reg [7:0] vmpr = 8'h00; // port 252. bit 7 is not used. R/W
|
||||
`else
|
||||
reg [7:0] vmpr = 8'b01100000; // port 252. bit 7 is not used. R/W. Mode 4 for simulation
|
||||
|
||||
`endif
|
||||
wire [1:0] screen_mode = vmpr[6:5];
|
||||
wire [4:0] screen_page = vmpr[4:0];
|
||||
|
||||
|
|
@ -130,9 +117,10 @@ module asic (
|
|||
wire rom_in_section_d = lmpr[6];
|
||||
wire write_protect_section_a = lmpr[7];
|
||||
|
||||
reg [7:0] hmpr = 8'h00; // port 251. Bit 7 is not used for now. R/W
|
||||
reg [7:0] hmpr = 8'h00; // port 251.
|
||||
wire [4:0] high_page = hmpr[4:0];
|
||||
wire [1:0] clut_mode_3_hi = hmpr[6:5];
|
||||
wire external_memory = hmpr[7];
|
||||
|
||||
reg [7:0] border = 8'h00; // port 254. Bit 6 not implemented. Write only.
|
||||
wire [3:0] clut_border = {border[5],border[2:0]};
|
||||
|
|
@ -166,15 +154,16 @@ module asic (
|
|||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Pixel counter and scan counter
|
||||
// Pixel counter (horizontal) and scan counter (vertical)
|
||||
reg [9:0] hc = 10'h000;
|
||||
reg [8:0] vc = 9'h000;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (hc != (HTOTAL-1))
|
||||
if (hc != (HTOTAL-1)) begin
|
||||
hc <= hc + 1;
|
||||
end
|
||||
else begin
|
||||
hc <= 10'h000;
|
||||
hc <= 10'h000;
|
||||
if (vc != (VTOTAL-1))
|
||||
vc <= vc + 1;
|
||||
else
|
||||
|
|
@ -183,24 +172,7 @@ module asic (
|
|||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HPEN and LPEN counters
|
||||
always @(posedge clk) begin
|
||||
if (hc[0] == 1'b0) begin
|
||||
if (hc == HACTIVEREGION) begin
|
||||
if (vc == VTOTAL-1)
|
||||
hpen <= 8'h00;
|
||||
else if (vc < VACTIVEREGION)
|
||||
hpen <= hpen + 1;
|
||||
end
|
||||
if (hc < HACTIVEREGION)
|
||||
lpen <= lpen + 1;
|
||||
else
|
||||
lpen <= 8'h00;
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Syncs and vertical retrace/raster line int generation
|
||||
// Syncs and vertical retrace/raster line interrupt generation
|
||||
reg vint_n;
|
||||
reg rint_n;
|
||||
|
||||
|
|
@ -208,39 +180,15 @@ module asic (
|
|||
csync = 1'b1;
|
||||
vint_n = 1'b1;
|
||||
rint_n = 1'b1;
|
||||
if (hc >= (HACTIVEREGION + RBORDER + HFPORCH) &&
|
||||
hc < (HACTIVEREGION + RBORDER + HFPORCH + HSYNC))
|
||||
csync = 1'b0;
|
||||
if ( (vc > BEGINVINTV && vc < (BEGINVINTV+4)) ||
|
||||
(vc == BEGINVINTV && hc >= BEGINVSYNCH) ||
|
||||
(vc == (BEGINVINTV+4) && hc < BEGINVSYNCH) )
|
||||
csync = ~csync;
|
||||
if ( (vc == BEGINVINTV && hc >= BEGINVINTH) ||
|
||||
(vc == ENDVINTV && hc < ENDVINTH) )
|
||||
// if (vc == BEGINVINTV && hc >= BEGINVINTH)
|
||||
vint_n = 1'b0;
|
||||
if (lineint >= 8'd0 && lineint <= 8'd191) begin
|
||||
// if (lineint == 8'd0) begin
|
||||
// if (vc == VTOTAL-1 && hc >= BEGINHINTH ||
|
||||
// vc == 9'd0 && hc < ENDHINTH)
|
||||
// rint_n = 1'b0;
|
||||
// end
|
||||
// else begin
|
||||
// if ({1'b0, lineint} == vc-1 && hc >= BEGINHINTH ||
|
||||
// {1'b0, lineint} == vc && hc < ENDHINTH)
|
||||
// rint_n = 1'b0;
|
||||
// end
|
||||
// end
|
||||
if (lineint == 8'd0) begin
|
||||
if (vc == VTOTAL-1 && hc >= BEGINHINTH)
|
||||
rint_n = 1'b0;
|
||||
end
|
||||
else begin
|
||||
if ({1'b0, lineint} == vc-1 && hc >= BEGINHINTH)
|
||||
rint_n = 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
if (hc >= (RBORDER + HFPORCH) && hc < (RBORDER + HFPORCH + HSYNC))
|
||||
csync = 1'b0;
|
||||
if (vc >= BEGINVSYNCV && vc < ENDVSYNCV)
|
||||
csync = ~csync;
|
||||
if (vc == BEGINVSYNCV && hc < 256)
|
||||
vint_n = 1'b0;
|
||||
if (lineint >= 8'd0 && lineint <= 8'd191)
|
||||
if ({1'b0, lineint} == vc && hc < 10'd256)
|
||||
rint_n = 1'b0;
|
||||
end
|
||||
assign int_n = vint_n & rint_n;
|
||||
|
||||
|
|
@ -249,7 +197,7 @@ module asic (
|
|||
reg fetching_pixels;
|
||||
|
||||
always @* begin
|
||||
if (vc>=0 && vc<VACTIVEREGION && hc>=0 && hc<HACTIVEREGION)
|
||||
if (vc>=0 && vc<VACTIVEREGION && hc>=256 && hc<HTOTAL)
|
||||
fetching_pixels = ~screen_off;
|
||||
else
|
||||
fetching_pixels = 1'b0;
|
||||
|
|
@ -260,14 +208,13 @@ module asic (
|
|||
reg blank_time;
|
||||
|
||||
always @* begin
|
||||
if ( (hc >= (HACTIVEREGION + RBORDER) &&
|
||||
hc < (HACTIVEREGION + RBORDER + HFPORCH + HSYNC + HBPORCH) ) ||
|
||||
(vc >= (VACTIVEREGION + BBORDER) &&
|
||||
vc < (VACTIVEREGION + BBORDER + VFPORCH + VSYNC + VBPORCH) ) ||
|
||||
(screen_off == 1'b1) )
|
||||
blank_time = 1'b1;
|
||||
else
|
||||
blank_time = 1'b0;
|
||||
blank_time = 1'b0;
|
||||
if (screen_off == 1'b1)
|
||||
blank_time = 1'b1;
|
||||
if (hc >= RBORDER && hc < (RBORDER + HFPORCH + HSYNC + HBPORCH))
|
||||
blank_time = 1'b1;
|
||||
if (vc >= (VACTIVEREGION + BBORDER) && vc < (VACTIVEREGION + BBORDER + VFPORCH + VSYNC + VBPORCH))
|
||||
blank_time = 1'b1;
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -277,20 +224,24 @@ module asic (
|
|||
|
||||
always @* begin
|
||||
mem_contention = 1'b0;
|
||||
io_contention = 1'b0;
|
||||
|
||||
if (hc[3:0]<4'd10)
|
||||
if (screen_off == 1'b0 && hc[3:0]<4'd10)
|
||||
io_contention = 1'b1;
|
||||
else
|
||||
io_contention = 1'b0;
|
||||
|
||||
if (screen_off == 1'b1 && (hc[3:0]==4'd0 ||
|
||||
hc[3:0]==4'd1 ||
|
||||
hc[3:0]==4'd8 ||
|
||||
hc[3:0]==4'd9) )
|
||||
io_contention = 1'b1;
|
||||
|
||||
if (fetching_pixels == 1'b1 && hc[3:0]<4'd10)
|
||||
mem_contention = 1'b1;
|
||||
else if (fetching_pixels == 1'b0 && (hc[3:0]==4'd0 ||
|
||||
hc[3:0]==4'd1 ||
|
||||
hc[3:0]==4'd8 ||
|
||||
hc[3:0]==4'd9) )
|
||||
if (fetching_pixels == 1'b0 && (hc[3:0]==4'd0 ||
|
||||
hc[3:0]==4'd1 ||
|
||||
hc[3:0]==4'd8 ||
|
||||
hc[3:0]==4'd9) )
|
||||
mem_contention = 1'b1;
|
||||
if (screen_mode == 2'b00 && hc[3:0]<4'd10 && hc[9:4]<6'd40)
|
||||
if (screen_mode == 2'b00 && hc[3:0]<4'd10 && (hc<10'd128 || hc>=10'd256))
|
||||
mem_contention = 1'b1; // extra contention for MODE 1
|
||||
end
|
||||
assign asic_is_using_ram = mem_contention & fetching_pixels;
|
||||
|
|
@ -305,7 +256,7 @@ module asic (
|
|||
wait_n = 1'b1;
|
||||
else if (mem_contention == 1'b1 && mreq_n == 1'b0)
|
||||
wait_n = 1'b0;
|
||||
else if (io_contention == 1'b1 && iorq_n == 1'b0)
|
||||
else if (io_contention == 1'b1 && iorq_n == 1'b0 && (rd_n == 1'b0 || wr_n == 1'b0))
|
||||
wait_n = 1'b0;
|
||||
end
|
||||
|
||||
|
|
@ -380,7 +331,7 @@ module asic (
|
|||
else begin // showing border
|
||||
sregm12 <= 8'h00;
|
||||
attrreg <= {1'b0, clut_border, 3'b000};
|
||||
sregm3 <= { {16{clut_border[1:0]}} };
|
||||
sregm3 <= { {16{clut_border[0],clut_border[1]}} };
|
||||
sregm4 <= { {8{clut_border}} };
|
||||
hibits_clut_m3 <= clut_border[3:2];
|
||||
end
|
||||
|
|
@ -411,7 +362,7 @@ module asic (
|
|||
else
|
||||
index = {attrreg[6],attrreg[5:3]};
|
||||
end
|
||||
2'd2: index = {hibits_clut_m3, sregm3[31:30]};
|
||||
2'd2: index = {hibits_clut_m3, sregm3[30], sregm3[31]};
|
||||
2'd3: index = sregm4[31:28];
|
||||
endcase
|
||||
if (blank_time == 1'b1)
|
||||
|
|
@ -424,6 +375,29 @@ module asic (
|
|||
assign b = {pixel[4], pixel[0]};
|
||||
assign bright = pixel[3];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HPEN and LPEN counters
|
||||
reg iorq_prev = 1'b1;
|
||||
reg [7:0] hpen_internal = 8'h00;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (hc == 10'd255 && vc == 9'd0) begin
|
||||
hpen_internal <= 8'h00;
|
||||
end
|
||||
else if (hc == (HTOTAL-1)) begin
|
||||
if (hpen_internal != 8'hC0)
|
||||
hpen_internal <= hpen_internal + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
iorq_prev <= iorq_n;
|
||||
if (iorq_prev == 1'b1 && iorq_n == 1'b0) begin // falling edge IORQ
|
||||
lpen <= (hc<10'd256 || vc>=9'd192)? {7'b0000000,index[0]} : (hc[8:1] ^ 8'h80); // fast way to add 128 to hc[8:1]
|
||||
hpen <= (screen_off == 1'b1)? 8'd192 : hpen_internal;
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPU memory address and control signal generation
|
||||
|
||||
|
|
@ -437,8 +411,11 @@ module asic (
|
|||
else if (mreq_n == 1'b0 && cpuaddr>=16'hC000 && rom_in_section_d==1'b1) begin
|
||||
romcs_n = 1'b0;
|
||||
end
|
||||
else if (mreq_n == 1'b0 /*&& (contention == 1'b0 || fetching_pixels == 1'b0)*/ ) begin
|
||||
ramcs_n = 1'b0;
|
||||
else if (mreq_n == 1'b0) begin
|
||||
if (cpuaddr >= 16'h8000 && external_memory == 1'b1) // disable internal RAM if bit 7 HMPR is set
|
||||
ramcs_n = 1'b1;
|
||||
else
|
||||
ramcs_n = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -476,11 +453,7 @@ module asic (
|
|||
// Write to IO ports from CPU
|
||||
always @(posedge clk) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
`ifdef SYNTH
|
||||
vmpr <= 8'h00;
|
||||
`else
|
||||
vmpr <= 8'b01100000;
|
||||
`endif
|
||||
lmpr <= 8'h00;
|
||||
hmpr <= 8'h00;
|
||||
border <= 8'h00;
|
||||
|
|
@ -512,7 +485,7 @@ module asic (
|
|||
if (iorq_n == 1'b0 && rd_n == 1'b0) begin
|
||||
data_enable_n = 1'b0;
|
||||
if (cpuaddr[7:0] == IOADDR_BORDER)
|
||||
data_to_cpu = {1'b0, ear, 1'b0, keyboard[4:0]};
|
||||
data_to_cpu = {screen_off, ear, 1'b0, keyboard[4:0]};
|
||||
else if (cpuaddr[7:0] == IOADDR_ATTRIB)
|
||||
data_to_cpu = vram_byte3;
|
||||
else if (cpuaddr[7:0] == IOADDR_STATUS)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 04:04:00 04/01/2012
|
||||
// Design Name:
|
||||
// Module Name: sigma_delta_dac
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define MSBI 8 // Most significant Bit of DAC input
|
||||
|
||||
//This is a Delta-Sigma Digital to Analog Converter
|
||||
module dac (DACout, DACin, Clk, Reset);
|
||||
output DACout; // This is the average output that feeds low pass filter
|
||||
input [`MSBI:0] DACin; // DAC input (excess 2**MSBI)
|
||||
input Clk;
|
||||
input Reset;
|
||||
|
||||
reg DACout; // for optimum performance, ensure that this ff is in IOB
|
||||
reg [`MSBI+2:0] DeltaAdder; // Output of Delta adder
|
||||
reg [`MSBI+2:0] SigmaAdder; // Output of Sigma adder
|
||||
reg [`MSBI+2:0] SigmaLatch = 1'b1 << (`MSBI+1); // Latches output of Sigma adder
|
||||
reg [`MSBI+2:0] DeltaB; // B input of Delta adder
|
||||
|
||||
always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1);
|
||||
always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB;
|
||||
always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch;
|
||||
always @(posedge Clk or posedge Reset)
|
||||
begin
|
||||
if(Reset)
|
||||
begin
|
||||
SigmaLatch <= #1 1'b1 << (`MSBI+1);
|
||||
DACout <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
SigmaLatch <= #1 SigmaAdder;
|
||||
DACout <= #1 SigmaLatch[`MSBI+2];
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module mixer (
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire ear,
|
||||
input wire mic,
|
||||
input wire spk,
|
||||
input wire [7:0] saa_left,
|
||||
input wire [7:0] saa_right,
|
||||
output wire audio_left,
|
||||
output wire audio_right
|
||||
);
|
||||
|
||||
reg [6:0] beeper;
|
||||
always @* begin
|
||||
beeper = 7'd0;
|
||||
if (ear == 1'b1)
|
||||
beeper = beeper + 7'd38; // 30% of total output
|
||||
if (mic == 1'b1)
|
||||
beeper = beeper + 7'd38; // 30% of total output
|
||||
if (spk == 1'b1)
|
||||
beeper = beeper + 7'd51; // 40% of total output
|
||||
end
|
||||
|
||||
wire [8:0] next_sample_l = beeper + saa_left;
|
||||
wire [8:0] next_sample_r = beeper + saa_right;
|
||||
|
||||
reg [8:0] sample_l, sample_r;
|
||||
always @(posedge clk) begin
|
||||
sample_l <= next_sample_l;
|
||||
sample_r <= next_sample_r;
|
||||
end
|
||||
|
||||
dac audio_dac_left (
|
||||
.DACout(audio_left),
|
||||
.DACin(sample_l),
|
||||
.Clk(clk),
|
||||
.Reset(~rst_n)
|
||||
);
|
||||
|
||||
dac audio_dac_right (
|
||||
.DACout(audio_right),
|
||||
.DACin(sample_r),
|
||||
.Clk(clk),
|
||||
.Reset(~rst_n)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
00
|
||||
05
|
||||
08
|
||||
0B
|
||||
0E
|
||||
10
|
||||
13
|
||||
15
|
||||
18
|
||||
1A
|
||||
1C
|
||||
1E
|
||||
20
|
||||
22
|
||||
24
|
||||
26
|
||||
28
|
||||
2A
|
||||
2C
|
||||
2E
|
||||
2F
|
||||
31
|
||||
33
|
||||
35
|
||||
36
|
||||
38
|
||||
3A
|
||||
3B
|
||||
3D
|
||||
3F
|
||||
40
|
||||
42
|
||||
44
|
||||
45
|
||||
47
|
||||
48
|
||||
4A
|
||||
4B
|
||||
4D
|
||||
4F
|
||||
50
|
||||
52
|
||||
53
|
||||
55
|
||||
56
|
||||
57
|
||||
59
|
||||
5A
|
||||
5C
|
||||
5D
|
||||
5F
|
||||
60
|
||||
62
|
||||
63
|
||||
64
|
||||
66
|
||||
67
|
||||
69
|
||||
6A
|
||||
6B
|
||||
6D
|
||||
6E
|
||||
6F
|
||||
71
|
||||
72
|
||||
73
|
||||
75
|
||||
76
|
||||
77
|
||||
79
|
||||
7A
|
||||
7B
|
||||
7D
|
||||
7E
|
||||
7F
|
||||
81
|
||||
82
|
||||
83
|
||||
84
|
||||
86
|
||||
87
|
||||
88
|
||||
89
|
||||
8B
|
||||
8C
|
||||
8D
|
||||
8E
|
||||
90
|
||||
91
|
||||
92
|
||||
93
|
||||
95
|
||||
96
|
||||
97
|
||||
98
|
||||
9A
|
||||
9B
|
||||
9C
|
||||
9D
|
||||
9E
|
||||
A0
|
||||
A1
|
||||
A2
|
||||
A3
|
||||
A4
|
||||
A6
|
||||
A7
|
||||
A8
|
||||
A9
|
||||
AA
|
||||
AB
|
||||
AD
|
||||
AE
|
||||
AF
|
||||
B0
|
||||
B1
|
||||
B2
|
||||
B4
|
||||
B5
|
||||
B6
|
||||
B7
|
||||
B8
|
||||
B9
|
||||
BA
|
||||
BC
|
||||
BD
|
||||
BE
|
||||
BF
|
||||
C0
|
||||
C1
|
||||
C2
|
||||
C4
|
||||
C5
|
||||
C6
|
||||
C7
|
||||
C8
|
||||
C9
|
||||
CA
|
||||
CB
|
||||
CC
|
||||
CE
|
||||
CF
|
||||
D0
|
||||
D1
|
||||
D2
|
||||
D3
|
||||
D4
|
||||
D5
|
||||
D6
|
||||
D7
|
||||
D9
|
||||
DA
|
||||
DB
|
||||
DC
|
||||
DD
|
||||
DE
|
||||
DF
|
||||
E0
|
||||
E1
|
||||
E2
|
||||
E3
|
||||
E4
|
||||
E5
|
||||
E6
|
||||
E8
|
||||
E9
|
||||
EA
|
||||
EB
|
||||
EC
|
||||
ED
|
||||
EE
|
||||
EF
|
||||
F0
|
||||
F1
|
||||
F2
|
||||
F3
|
||||
F4
|
||||
F5
|
||||
F6
|
||||
F7
|
||||
F8
|
||||
F9
|
||||
FA
|
||||
FB
|
||||
FC
|
||||
FD
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
FF
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define GAMMA 0.75
|
||||
|
||||
int main()
|
||||
{
|
||||
FILE *f;
|
||||
int i,v;
|
||||
double x;
|
||||
|
||||
f = fopen ("compressor_lut.hex", "wt");
|
||||
for (i=0;i<256;i++)
|
||||
{
|
||||
if (i<=186)
|
||||
{
|
||||
x = i/186.0;
|
||||
v = 255*pow(x,GAMMA);
|
||||
}
|
||||
else
|
||||
v = 255;
|
||||
printf ("%4d -> %4d\n", i, v);
|
||||
fprintf (f, "%.2X\n", v);
|
||||
}
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// Engineer: Miguel Angel Rodriguez Jodar
|
||||
//
|
||||
// Create Date: 15:18:53 06/03/2015
|
||||
// Design Name:
|
||||
// Module Name: ps2_keyb
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Create Date: 15:18:53 03/06/2015
|
||||
// Design Name: SAM Coupé clone
|
||||
// Module Name: ps2_keyb
|
||||
// Project Name: SAM Coupé clone
|
||||
// Target Devices: Spartan 6
|
||||
// Tool versions: ISE 12.4
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
|
|
|
|||
|
|
@ -74,10 +74,11 @@ module relojes
|
|||
// Clock out ports
|
||||
output wire CLK_OUT1,
|
||||
output wire CLK_OUT2,
|
||||
output wire CLK_OUT3
|
||||
output wire CLK_OUT3,
|
||||
output wire CLK_OUT4
|
||||
);
|
||||
|
||||
wire clkin1, clkout0, clkout1, clkout2;
|
||||
wire clkin1, clkout0, clkout1, clkout2, clkout3;
|
||||
|
||||
// Input buffering
|
||||
//------------------------------------
|
||||
|
|
@ -95,7 +96,6 @@ module relojes
|
|||
wire drdy_unused;
|
||||
wire locked_unused;
|
||||
wire clkfbout;
|
||||
wire clkout3_unused;
|
||||
wire clkout4_unused;
|
||||
wire clkout5_unused;
|
||||
|
||||
|
|
@ -114,7 +114,10 @@ module relojes
|
|||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_DIVIDE (100),
|
||||
.CLKOUT2_PHASE (0.000),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKOUT3_DIVIDE (75),
|
||||
.CLKOUT3_PHASE (0.000),
|
||||
.CLKOUT3_DUTY_CYCLE (0.500),
|
||||
.CLKIN_PERIOD (20.0),
|
||||
.REF_JITTER (0.010))
|
||||
pll_base_inst
|
||||
|
|
@ -123,7 +126,7 @@ module relojes
|
|||
.CLKOUT0 (clkout0),
|
||||
.CLKOUT1 (clkout1),
|
||||
.CLKOUT2 (clkout2),
|
||||
.CLKOUT3 (clkout3_unused),
|
||||
.CLKOUT3 (clkout3),
|
||||
.CLKOUT4 (clkout4_unused),
|
||||
.CLKOUT5 (clkout5_unused),
|
||||
.LOCKED (locked_unused),
|
||||
|
|
@ -141,7 +144,6 @@ module relojes
|
|||
(.O (CLK_OUT1),
|
||||
.I (clkout0));
|
||||
|
||||
|
||||
BUFG clkout2_buf
|
||||
(.O (CLK_OUT2),
|
||||
.I (clkout1));
|
||||
|
|
@ -150,6 +152,8 @@ module relojes
|
|||
(.O (CLK_OUT3),
|
||||
.I (clkout2));
|
||||
|
||||
|
||||
BUFG clkout4_buf
|
||||
(.O (CLK_OUT4),
|
||||
.I (clkout3));
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,645 @@
|
|||
`timescale 1ns / 1ps
|
||||
`default_nettype none
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer: Miguel Angel Rodriguez Jodar
|
||||
//
|
||||
// Create Date: 17:20:11 08/09/2015
|
||||
// Design Name: SAM Coupé clone
|
||||
// Module Name: saa1099
|
||||
// Project Name: SAM Coupé clone
|
||||
// Target Devices: Spartan 6
|
||||
// Tool versions: ISE 12.4
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module saa1099 (
|
||||
input wire clk, // 8 MHz
|
||||
input wire rst_n,
|
||||
input wire cs_n,
|
||||
input wire a0, // 0=data, 1=address
|
||||
input wire wr_n,
|
||||
input wire [7:0] din,
|
||||
output wire [7:0] out_l,
|
||||
output wire [7:0] out_r
|
||||
);
|
||||
// DTACK is not implemented. Sorry about that
|
||||
|
||||
reg [7:0] amplit0, amplit1, amplit2, amplit3, amplit4, amplit5;
|
||||
reg [8:0] freq0, freq1, freq2, freq3, freq4, freq5;
|
||||
reg [7:0] oct10, oct32, oct54;
|
||||
reg [7:0] freqenable;
|
||||
reg [7:0] noiseenable;
|
||||
reg [7:0] noisegen;
|
||||
reg [7:0] envelope0, envelope1;
|
||||
reg [7:0] ctrl; // frequency reset and sound enable for all channels
|
||||
|
||||
reg [4:0] addr; // holds the address of the register to write to
|
||||
|
||||
// Write values into internal registers
|
||||
always @(posedge clk) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
ctrl <= 8'h00;
|
||||
end
|
||||
else begin
|
||||
if (cs_n == 1'b0 && wr_n == 1'b0) begin
|
||||
if (a0 == 1'b1)
|
||||
addr <= din[4:0];
|
||||
else begin
|
||||
case (addr)
|
||||
5'h00: amplit0 <= din;
|
||||
5'h01: amplit1 <= din;
|
||||
5'h02: amplit2 <= din;
|
||||
5'h03: amplit3 <= din;
|
||||
5'h04: amplit4 <= din;
|
||||
5'h05: amplit5 <= din;
|
||||
|
||||
5'h08: freq0 <= 9'd510 - {1'b0, din};
|
||||
5'h09: freq1 <= 9'd510 - {1'b0, din};
|
||||
5'h0A: freq2 <= 9'd510 - {1'b0, din};
|
||||
5'h0B: freq3 <= 9'd510 - {1'b0, din};
|
||||
5'h0C: freq4 <= 9'd510 - {1'b0, din};
|
||||
5'h0D: freq5 <= 9'd510 - {1'b0, din};
|
||||
|
||||
5'h10: oct10 <= din;
|
||||
5'h11: oct32 <= din;
|
||||
5'h12: oct54 <= din;
|
||||
|
||||
5'h14: freqenable <= din;
|
||||
5'h15: noiseenable <= din;
|
||||
5'h16: noisegen <= din;
|
||||
|
||||
5'h18: envelope0 <= din;
|
||||
5'h19: envelope1 <= din;
|
||||
|
||||
5'h1C: ctrl <= din;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire gen0_tone;
|
||||
wire gen1_tone;
|
||||
wire gen2_tone;
|
||||
wire gen3_tone;
|
||||
wire gen4_tone;
|
||||
wire gen5_tone;
|
||||
|
||||
wire pulse_to_noise0, pulse_to_envelope0;
|
||||
wire pulse_to_noise1, pulse_to_envelope1;
|
||||
|
||||
wire noise0, noise1;
|
||||
|
||||
wire [4:0] mixout0_l, mixout0_r;
|
||||
wire [4:0] mixout1_l, mixout1_r;
|
||||
wire [4:0] mixout2_l, mixout2_r;
|
||||
wire [4:0] mixout2_l_with_env, mixout2_r_with_env;
|
||||
wire [4:0] mixout3_l, mixout3_r;
|
||||
wire [4:0] mixout4_l, mixout4_r;
|
||||
wire [4:0] mixout5_l, mixout5_r;
|
||||
wire [4:0] mixout5_l_with_env, mixout5_r_with_env;
|
||||
|
||||
// Frequency and noise generators, top half
|
||||
|
||||
saa1099_tone_gen freq_gen0 (
|
||||
.clk(clk),
|
||||
.octave(oct10[2:0]),
|
||||
.freq(freq0),
|
||||
.out(gen0_tone),
|
||||
.pulseout(pulse_to_noise0)
|
||||
);
|
||||
|
||||
saa1099_tone_gen freq_gen1 (
|
||||
.clk(clk),
|
||||
.octave(oct10[6:4]),
|
||||
.freq(freq1),
|
||||
.out(gen1_tone),
|
||||
.pulseout(pulse_to_envelope0)
|
||||
);
|
||||
|
||||
saa1099_tone_gen freq_gen2 (
|
||||
.clk(clk),
|
||||
.octave(oct32[2:0]),
|
||||
.freq(freq2),
|
||||
.out(gen2_tone),
|
||||
.pulseout()
|
||||
);
|
||||
|
||||
saa1099_noise_gen noise_gen0 (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.pulse_from_gen(pulse_to_noise0),
|
||||
.noise_freq(noisegen[1:0]),
|
||||
.out(noise0)
|
||||
);
|
||||
|
||||
|
||||
// Frequency and noise generators, bottom half
|
||||
|
||||
saa1099_tone_gen freq_gen3 (
|
||||
.clk(clk),
|
||||
.octave(oct32[6:4]),
|
||||
.freq(freq3),
|
||||
.out(gen3_tone),
|
||||
.pulseout(pulse_to_noise1)
|
||||
);
|
||||
|
||||
saa1099_tone_gen freq_gen4 (
|
||||
.clk(clk),
|
||||
.octave(oct54[2:0]),
|
||||
.freq(freq4),
|
||||
.out(gen4_tone),
|
||||
.pulseout(pulse_to_envelope1)
|
||||
);
|
||||
|
||||
saa1099_tone_gen freq_gen5 (
|
||||
.clk(clk),
|
||||
.octave(oct54[6:4]),
|
||||
.freq(freq5),
|
||||
.out(gen5_tone),
|
||||
.pulseout()
|
||||
);
|
||||
|
||||
saa1099_noise_gen noise_gen1 (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.pulse_from_gen(pulse_to_noise1),
|
||||
.noise_freq(noisegen[5:4]),
|
||||
.out(noise1)
|
||||
);
|
||||
|
||||
|
||||
// Mixers
|
||||
|
||||
sa1099_mixer_and_amplitude mixer0 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[0] == 1'b1 && noisegen[1:0] != 2'd3), // if gen0 is being used to generate noise, don't use this channel for tone output
|
||||
.en_noise(noiseenable[0]),
|
||||
.tone(gen0_tone),
|
||||
.noise(noise0),
|
||||
.amplitude_l(amplit0[3:0]),
|
||||
.amplitude_r(amplit0[7:4]),
|
||||
.out_l(mixout0_l),
|
||||
.out_r(mixout0_r)
|
||||
);
|
||||
|
||||
sa1099_mixer_and_amplitude mixer1 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[1] == 1'b1 && envelope0[7] == 1'b0),
|
||||
.en_noise(noiseenable[1]),
|
||||
.tone(gen1_tone),
|
||||
.noise(noise0),
|
||||
.amplitude_l(amplit1[3:0]),
|
||||
.amplitude_r(amplit1[7:4]),
|
||||
.out_l(mixout1_l),
|
||||
.out_r(mixout1_r)
|
||||
);
|
||||
|
||||
sa1099_mixer_and_amplitude mixer2 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[2]),
|
||||
.en_noise(noiseenable[2]),
|
||||
.tone(gen2_tone),
|
||||
.noise(noise0),
|
||||
.amplitude_l(amplit2[3:0]),
|
||||
.amplitude_r(amplit2[7:4]),
|
||||
.out_l(mixout2_l),
|
||||
.out_r(mixout2_r)
|
||||
);
|
||||
|
||||
sa1099_mixer_and_amplitude mixer3 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[3] == 1'b1 && noisegen[5:4] != 2'd3), // if gen3 is being used to generate noise, don't use this channel for tone output
|
||||
.en_noise(noiseenable[3]),
|
||||
.tone(gen3_tone),
|
||||
.noise(noise1),
|
||||
.amplitude_l(amplit3[3:0]),
|
||||
.amplitude_r(amplit3[7:4]),
|
||||
.out_l(mixout3_l),
|
||||
.out_r(mixout3_r)
|
||||
);
|
||||
|
||||
sa1099_mixer_and_amplitude mixer4 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[4] == 1'b1 && envelope1[7] == 1'b0),
|
||||
.en_noise(noiseenable[4]),
|
||||
.tone(gen4_tone),
|
||||
.noise(noise1),
|
||||
.amplitude_l(amplit4[3:0]),
|
||||
.amplitude_r(amplit4[7:4]),
|
||||
.out_l(mixout4_l),
|
||||
.out_r(mixout4_r)
|
||||
);
|
||||
|
||||
sa1099_mixer_and_amplitude mixer5 (
|
||||
.clk(clk),
|
||||
.en_tone(freqenable[5]),
|
||||
.en_noise(noiseenable[5]),
|
||||
.tone(gen5_tone),
|
||||
.noise(noise1),
|
||||
.amplitude_l(amplit5[3:0]),
|
||||
.amplitude_r(amplit5[7:4]),
|
||||
.out_l(mixout5_l),
|
||||
.out_r(mixout5_r)
|
||||
);
|
||||
|
||||
|
||||
// Envelope generators
|
||||
|
||||
saa1099_envelope_gen envelope_gen0 (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.envreg(envelope0),
|
||||
.write_to_envreg_addr(cs_n == 1'b0 && wr_n == 1'b0 && a0 == 1'b1 && din[4:0] == 5'h18),
|
||||
.write_to_envreg_data(cs_n == 1'b0 && wr_n == 1'b0 && a0 == 1'b0 && addr == 5'h18),
|
||||
.pulse_from_tonegen(pulse_to_envelope0),
|
||||
.tone_en(freqenable[2]),
|
||||
.noise_en(noiseenable[2]),
|
||||
.sound_in_left(mixout2_l),
|
||||
.sound_in_right(mixout2_r),
|
||||
.sound_out_left(mixout2_l_with_env),
|
||||
.sound_out_right(mixout2_r_with_env)
|
||||
);
|
||||
|
||||
saa1099_envelope_gen envelope_gen1 (
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.envreg(envelope1),
|
||||
.write_to_envreg_addr(cs_n == 1'b0 && wr_n == 1'b0 && a0 == 1'b1 && din[4:0] == 5'h19),
|
||||
.write_to_envreg_data(cs_n == 1'b0 && wr_n == 1'b0 && a0 == 1'b0 && addr == 5'h19),
|
||||
.pulse_from_tonegen(pulse_to_envelope1),
|
||||
.tone_en(freqenable[5]),
|
||||
.noise_en(noiseenable[5]),
|
||||
.sound_in_left(mixout5_l),
|
||||
.sound_in_right(mixout5_r),
|
||||
.sound_out_left(mixout5_l_with_env),
|
||||
.sound_out_right(mixout5_r_with_env)
|
||||
);
|
||||
|
||||
// Final mix
|
||||
|
||||
saa1099_output_mixer outmix_left (
|
||||
.clk(clk),
|
||||
.sound_enable(ctrl[0]),
|
||||
.i0(mixout0_l),
|
||||
.i1(mixout1_l),
|
||||
.i2(mixout2_l_with_env),
|
||||
.i3(mixout3_l),
|
||||
.i4(mixout4_l),
|
||||
.i5(mixout5_l_with_env),
|
||||
.o(out_l)
|
||||
);
|
||||
|
||||
saa1099_output_mixer outmix_right (
|
||||
.clk(clk),
|
||||
.sound_enable(ctrl[0]),
|
||||
.i0(mixout0_r),
|
||||
.i1(mixout1_r),
|
||||
.i2(mixout2_r_with_env),
|
||||
.i3(mixout3_r),
|
||||
.i4(mixout4_r),
|
||||
.i5(mixout5_r_with_env),
|
||||
.o(out_r)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
module saa1099_tone_gen (
|
||||
input wire clk,
|
||||
input wire [2:0] octave,
|
||||
input wire [8:0] freq,
|
||||
output reg out,
|
||||
output reg pulseout
|
||||
);
|
||||
|
||||
reg [7:0] fcounter;
|
||||
always @* begin
|
||||
case (octave)
|
||||
3'd0: fcounter = 8'd255;
|
||||
3'd1: fcounter = 8'd127;
|
||||
3'd2: fcounter = 8'd63;
|
||||
3'd3: fcounter = 8'd31;
|
||||
3'd4: fcounter = 8'd15;
|
||||
3'd5: fcounter = 8'd7;
|
||||
3'd6: fcounter = 8'd3;
|
||||
3'd7: fcounter = 8'd1;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [7:0] count = 8'd0;
|
||||
always @(posedge clk) begin
|
||||
if (count == fcounter)
|
||||
count <= 8'd0;
|
||||
else
|
||||
count <= count + 1;
|
||||
end
|
||||
|
||||
reg pulse;
|
||||
always @* begin
|
||||
if (count == fcounter)
|
||||
pulse = 1'b1;
|
||||
else
|
||||
pulse = 1'b0;
|
||||
end
|
||||
|
||||
initial out = 1'b0;
|
||||
reg [8:0] cfinal = 9'd0;
|
||||
always @(posedge clk) begin
|
||||
if (pulse == 1'b1) begin
|
||||
if (cfinal == freq) begin
|
||||
cfinal <= 9'd0;
|
||||
out <= ~out;
|
||||
end
|
||||
else
|
||||
cfinal <= cfinal + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @* begin
|
||||
if (pulse == 1'b1 && cfinal == freq)
|
||||
pulseout = 1'b1;
|
||||
else
|
||||
pulseout = 1'b0;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module saa1099_noise_gen (
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire pulse_from_gen,
|
||||
input wire [1:0] noise_freq,
|
||||
output wire out
|
||||
);
|
||||
|
||||
reg [10:0] fcounter;
|
||||
always @* begin
|
||||
case (noise_freq)
|
||||
2'd0: fcounter = 11'd255;
|
||||
2'd1: fcounter = 11'd511;
|
||||
2'd2: fcounter = 11'd1023;
|
||||
default: fcounter = 11'd2047; // actually not used
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [10:0] count = 11'd0;
|
||||
always @(posedge clk) begin
|
||||
if (count == fcounter)
|
||||
count <= 11'd0;
|
||||
else
|
||||
count <= count + 1;
|
||||
end
|
||||
|
||||
reg [30:0] lfsr = 31'h11111111;
|
||||
always @(posedge clk) begin
|
||||
if (rst_n == 1'b0)
|
||||
lfsr <= 31'h11111111; // just a seed
|
||||
if ((noise_freq == 2'd3 && pulse_from_gen == 1'b1) ||
|
||||
(noise_freq != 2'd3 && count == fcounter)) begin
|
||||
if ((lfsr[2] ^ lfsr[30]) == 1'b1)
|
||||
lfsr <= {lfsr[29:0], 1'b1};
|
||||
else
|
||||
lfsr <= {lfsr[29:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
assign out = lfsr[0];
|
||||
|
||||
endmodule
|
||||
|
||||
module sa1099_mixer_and_amplitude (
|
||||
input wire clk,
|
||||
input wire en_tone,
|
||||
input wire en_noise,
|
||||
input wire tone,
|
||||
input wire noise,
|
||||
input wire [3:0] amplitude_l,
|
||||
input wire [3:0] amplitude_r,
|
||||
output reg [4:0] out_l,
|
||||
output reg [4:0] out_r
|
||||
);
|
||||
|
||||
reg [4:0] next_out_l, next_out_r;
|
||||
always @* begin
|
||||
next_out_l = 5'b0000;
|
||||
next_out_r = 5'b0000;
|
||||
if (en_tone == 1'b1)
|
||||
if (tone == 1'b1) begin
|
||||
next_out_l = next_out_l + {1'b0, amplitude_l};
|
||||
next_out_r = next_out_r + {1'b0, amplitude_r};
|
||||
end
|
||||
if (en_noise == 1'b1)
|
||||
if (noise == 1'b1) begin
|
||||
next_out_l = next_out_l + {1'b0, amplitude_l};
|
||||
next_out_r = next_out_r + {1'b0, amplitude_r};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
out_l <= next_out_l;
|
||||
out_r <= next_out_r;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module saa1099_envelope_gen (
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire [7:0] envreg,
|
||||
input wire write_to_envreg_addr,
|
||||
input wire write_to_envreg_data,
|
||||
input wire pulse_from_tonegen,
|
||||
input wire tone_en,
|
||||
input wire noise_en,
|
||||
input wire [4:0] sound_in_left,
|
||||
input wire [4:0] sound_in_right,
|
||||
output wire [4:0] sound_out_left,
|
||||
output wire [4:0] sound_out_right
|
||||
);
|
||||
|
||||
reg [3:0] envelopes[0:511];
|
||||
integer i;
|
||||
initial begin
|
||||
// Generating envelopes
|
||||
// 0 0 0 : ______________
|
||||
for (i=0;i<64;i=i+1)
|
||||
envelopes[{3'b000,i[5:0]}] = 4'd0;
|
||||
|
||||
// 0 0 1 : --------------
|
||||
for (i=0;i<64;i=i+1)
|
||||
envelopes[{3'b001,i[5:0]}] = 4'd15;
|
||||
|
||||
// 0 1 0 : \_____________
|
||||
for (i=0;i<16;i=i+1)
|
||||
envelopes[{3'b010,i[5:0]}] = ~i[3:0];
|
||||
for (i=16;i<64;i=i+1)
|
||||
envelopes[{3'b010,i[5:0]}] = 4'd0;
|
||||
|
||||
// 0 1 1 : \|\|\|\|\|\|\|\
|
||||
for (i=0;i<64;i=i+1)
|
||||
envelopes[{3'b011,i[5:0]}] = ~i[3:0];
|
||||
|
||||
// 1 0 0 : /\______________
|
||||
for (i=0;i<16;i=i+1)
|
||||
envelopes[{3'b100,i[5:0]}] = i[3:0];
|
||||
for (i=16;i<32;i=i+1)
|
||||
envelopes[{3'b100,i[5:0]}] = ~i[3:0];
|
||||
for (i=32;i<64;i=i+1)
|
||||
envelopes[{3'b100,i[5:0]}] = 4'd0;
|
||||
|
||||
// 1 0 1 : /\/\/\/\/\/\/\/\
|
||||
for (i=0;i<16;i=i+1)
|
||||
envelopes[{3'b101,i[5:0]}] = i[3:0];
|
||||
for (i=16;i<32;i=i+1)
|
||||
envelopes[{3'b101,i[5:0]}] = ~i[3:0];
|
||||
for (i=32;i<48;i=i+1)
|
||||
envelopes[{3'b101,i[5:0]}] = i[3:0];
|
||||
for (i=48;i<64;i=i+1)
|
||||
envelopes[{3'b101,i[5:0]}] = ~i[3:0];
|
||||
|
||||
// 1 1 0 : /|________________
|
||||
for (i=0;i<16;i=i+1)
|
||||
envelopes[{3'b110,i[5:0]}] = i[3:0];
|
||||
for (i=16;i<64;i=i+1)
|
||||
envelopes[{3'b110,i[5:0]}] = 4'd0;
|
||||
|
||||
// 1 1 1 : /|/|/|/|/|/|/|/|/|
|
||||
for (i=0;i<64;i=i+1)
|
||||
envelopes[{3'b111,i[5:0]}] = i[3:0];
|
||||
end
|
||||
|
||||
reg write_to_address_prev = 1'b0;
|
||||
wire write_to_address_edge = (~write_to_address_prev & write_to_envreg_addr);
|
||||
|
||||
reg write_to_data_prev = 1'b0;
|
||||
wire write_to_data_edge = (~write_to_data_prev & write_to_envreg_data);
|
||||
|
||||
reg [2:0] envshape = 3'b000;
|
||||
reg stereoshape = 1'b0;
|
||||
reg envclock = 1'b0;
|
||||
wire env_enable = envreg[7];
|
||||
wire env_resolution = envreg[4];
|
||||
|
||||
reg pending_data = 1'b0;
|
||||
|
||||
reg [5:0] envcounter = 6'd0;
|
||||
always @(posedge clk) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
envcounter <= 6'd0;
|
||||
stereoshape <= 1'b0;
|
||||
envshape <= 3'b000;
|
||||
envclock <= 1'b0;
|
||||
write_to_address_prev = 1'b0;
|
||||
write_to_data_prev = 1'b0;
|
||||
pending_data <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
write_to_address_prev <= write_to_envreg_addr;
|
||||
write_to_data_prev <= write_to_envreg_data;
|
||||
if (write_to_data_edge == 1'b1)
|
||||
pending_data <= 1'b1;
|
||||
if (env_enable == 1'b1) begin
|
||||
if (envclock == 1'b0 && pulse_from_tonegen == 1'b1 || envclock == 1'b1 && write_to_address_edge == 1'b1) begin // pulse from internal or external clock?
|
||||
if (envcounter == 6'd63)
|
||||
envcounter <= 6'd32;
|
||||
else begin
|
||||
if (env_resolution == 1'b0)
|
||||
envcounter <= envcounter + 1;
|
||||
else
|
||||
envcounter <= envcounter + 2;
|
||||
end
|
||||
if (envcounter == 6'd0 ||
|
||||
envcounter >= 6'd15 && (envshape == 3'b000 || envshape == 3'b010 || envshape == 3'b110) ||
|
||||
envcounter[3:0] == 4'd15 && (envshape == 3'b001 || envshape == 3'b011 || envshape == 3'b111) ||
|
||||
envcounter >= 6'd31 && envshape == 3'b100 ||
|
||||
envcounter[4:0] == 5'd31 && envshape ==3'b101) begin // find out when to updated buffered values
|
||||
if (pending_data == 1'b1) begin // if we reached one of the designated points (3) or (4) and there is pending data, load it
|
||||
envshape <= envreg[3:1];
|
||||
stereoshape <= envreg[0];
|
||||
envclock <= envreg[5];
|
||||
envcounter <= 6'd0;
|
||||
pending_data <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [3:0] envleft = 4'b0000;
|
||||
wire [3:0] envright = (stereoshape == 1'b0)? envleft : ~envleft; // bit 0 of envreg inverts envelope shape
|
||||
always @(posedge clk)
|
||||
envleft <= envelopes[{envshape,envcounter}]; // take current envelope from envelopes ROM
|
||||
|
||||
wire [4:0] temp_out_left, temp_out_right;
|
||||
|
||||
saa1099_amp_env_mixer modulate_left (
|
||||
.a(sound_in_left),
|
||||
.b(envleft),
|
||||
.o(temp_out_left)
|
||||
);
|
||||
|
||||
saa1099_amp_env_mixer modulate_right (
|
||||
.a(sound_in_right),
|
||||
.b(envright),
|
||||
.o(temp_out_right)
|
||||
);
|
||||
|
||||
assign sound_out_left = (env_enable == 1'b0)? sound_in_left : // if envelopes are not enabled, just bypass them
|
||||
(env_enable == 1'b1 && tone_en == 1'b0 && noise_en == 1'b0)? {envleft, envleft[3]} : // if tone and noise are off, output is envelope signal itself
|
||||
temp_out_left; // else it is original signal modulated by envelope
|
||||
|
||||
assign sound_out_right = (env_enable == 1'b0)? sound_in_right :
|
||||
(env_enable == 1'b1 && tone_en == 1'b0 && noise_en == 1'b0)? {envright, envright[3]} :
|
||||
temp_out_right;
|
||||
endmodule
|
||||
|
||||
module saa1099_amp_env_mixer (
|
||||
input wire [4:0] a, // amplitude
|
||||
input wire [3:0] b, // envelope
|
||||
output wire [4:0] o // output
|
||||
);
|
||||
|
||||
wire [6:0] res1 = ((b[0] == 1'b1)? a : 5'h00) + ((b[1] == 1'b1)? {a,1'b0} : 6'h00);
|
||||
wire [8:0] res2 = ((b[2] == 1'b1)? {a,2'b00} : 7'h00) + ((b[3] == 1'b1)? {a,3'b000} : 8'h00);
|
||||
wire [8:0] res3 = res1 + res2;
|
||||
assign o = res3[8:4];
|
||||
endmodule
|
||||
|
||||
module saa1099_output_mixer (
|
||||
input wire clk,
|
||||
input wire sound_enable,
|
||||
input wire [4:0] i0,
|
||||
input wire [4:0] i1,
|
||||
input wire [4:0] i2,
|
||||
input wire [4:0] i3,
|
||||
input wire [4:0] i4,
|
||||
input wire [4:0] i5,
|
||||
output reg [7:0] o
|
||||
);
|
||||
|
||||
reg [7:0] compressor_table[0:255];
|
||||
initial begin
|
||||
$readmemh ("compressor_lut.hex", compressor_table);
|
||||
end
|
||||
|
||||
reg [7:0] mix;
|
||||
always @* begin
|
||||
if (sound_enable == 1'b1)
|
||||
mix = i0 + i1 + i2 + i3 + i4 + i5;
|
||||
else
|
||||
mix = 8'd0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
o <= compressor_table[mix];
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
// Engineer: Miguel Angel Rodriguez Jodar
|
||||
//
|
||||
// Create Date: 03:54:40 07/25/2015
|
||||
// Design Name:
|
||||
// Module Name: samcoupe
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Create Date: 03:54:40 13/25/2015
|
||||
// Design Name: SAM Coupé clone
|
||||
// Module Name: samcoupe
|
||||
// Project Name: SAM Coupé clone
|
||||
// Target Devices: Spartan 6
|
||||
// Tool versions: ISE 12.4
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
|
|
@ -24,6 +24,7 @@ module samcoupe (
|
|||
input wire clk24,
|
||||
input wire clk12,
|
||||
input wire clk6,
|
||||
input wire clk8,
|
||||
input wire master_reset_n,
|
||||
// Video output
|
||||
output wire [1:0] r,
|
||||
|
|
@ -82,8 +83,7 @@ module samcoupe (
|
|||
|
||||
// Audio signals
|
||||
wire mic, beep;
|
||||
assign audio_out_left = ear;
|
||||
assign audio_out_right = beep;
|
||||
wire [7:0] saa_out_l, saa_out_r;
|
||||
|
||||
// MUX from memory/devices to Z80 data bus
|
||||
assign data_to_cpu = (rom_oe_n == 1'b0)? data_from_rom :
|
||||
|
|
@ -158,30 +158,12 @@ module samcoupe (
|
|||
.dout(data_from_rom)
|
||||
);
|
||||
|
||||
// ram_dual_port_turnos ram_512k (
|
||||
// .clk(clk24),
|
||||
// .whichturn(asic_is_using_ram),
|
||||
// .vramaddr(vramaddr),
|
||||
// .cpuramaddr(cpuramaddr),
|
||||
// .cpu_we_n(ram_we_n),
|
||||
// .data_from_cpu(data_from_cpu),
|
||||
// .data_to_asic(data_to_asic),
|
||||
// .data_to_cpu(data_from_ram),
|
||||
// // Actual interface with SRAM
|
||||
// .sram_a(sram_addr),
|
||||
// .sram_we_n(sram_we_n),
|
||||
// .sram_d(sram_data)
|
||||
// );
|
||||
|
||||
ram_dual_port ram_512k (
|
||||
ram_dual_port_turnos ram_512k (
|
||||
.clk(clk24),
|
||||
.whichturn(asic_is_using_ram),
|
||||
.vramaddr(vramaddr),
|
||||
.cpuramaddr(cpuramaddr),
|
||||
.mreq_n(ram_oe_n),
|
||||
.rd_n(rd_n),
|
||||
.wr_n(ram_we_n),
|
||||
.rfsh_n(rfsh_n),
|
||||
.cpu_we_n(ram_we_n),
|
||||
.data_from_cpu(data_from_cpu),
|
||||
.data_to_asic(data_to_asic),
|
||||
.data_to_cpu(data_from_ram),
|
||||
|
|
@ -190,20 +172,25 @@ module samcoupe (
|
|||
.sram_we_n(sram_we_n),
|
||||
.sram_d(sram_data)
|
||||
);
|
||||
|
||||
// ps2k el_teclado (
|
||||
// .clk(clk6),
|
||||
// .ps2clk(clkps2),
|
||||
// .ps2data(dataps2),
|
||||
// .rows(kbrows[7:0]),
|
||||
// .cols(kbcolumns[4:0]),
|
||||
// .joy(), // Implementación joystick kempston en teclado numerico
|
||||
// .scancode(), // El scancode original desde el teclado
|
||||
// .rst(kb_rst_n), // esto son salidas, no entradas
|
||||
// .nmi(kb_nmi_n), // Señales de reset y NMI
|
||||
// .mrst() // generadas por pulsaciones especiales del teclado
|
||||
// );
|
||||
|
||||
// ram_dual_port ram_512k (
|
||||
// .clk(clk24),
|
||||
// .whichturn(asic_is_using_ram),
|
||||
// .vramaddr(vramaddr),
|
||||
// .cpuramaddr(cpuramaddr),
|
||||
// .mreq_n(ram_oe_n),
|
||||
// .rd_n(rd_n),
|
||||
// .wr_n(ram_we_n),
|
||||
// .rfsh_n(rfsh_n),
|
||||
// .data_from_cpu(data_from_cpu),
|
||||
// .data_to_asic(data_to_asic),
|
||||
// .data_to_cpu(data_from_ram),
|
||||
// // Actual interface with SRAM
|
||||
// .sram_a(sram_addr),
|
||||
// .sram_we_n(sram_we_n),
|
||||
// .sram_d(sram_data)
|
||||
// );
|
||||
|
||||
ps2_keyb el_teclado (
|
||||
.clk(clk6),
|
||||
.clkps2(clkps2),
|
||||
|
|
@ -228,4 +215,28 @@ module samcoupe (
|
|||
.kbstatus_dout(),
|
||||
.oe_n_kbstatus()
|
||||
);
|
||||
|
||||
saa1099 el_saa (
|
||||
.clk(clk8), // 8 MHz
|
||||
.rst_n(kb_rst_n),
|
||||
.cs_n(~(cpuaddr[7:0] == 8'hFF && iorq_n == 1'b0)),
|
||||
.a0(cpuaddr[8]), // 0=data, 1=address
|
||||
.wr_n(wr_n),
|
||||
.din(data_from_cpu),
|
||||
.out_l(saa_out_l),
|
||||
.out_r(saa_out_r)
|
||||
);
|
||||
|
||||
mixer sam_audio_mixer (
|
||||
.clk(clk8),
|
||||
.rst_n(kb_rst_n),
|
||||
.ear(ear),
|
||||
.mic(mic),
|
||||
.spk(beep),
|
||||
.saa_left(saa_out_l),
|
||||
.saa_right(saa_out_r),
|
||||
.audio_left(audio_out_left),
|
||||
.audio_right(audio_out_right)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -85,6 +85,14 @@
|
|||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="Implementation"/>
|
||||
</file>
|
||||
<file xil_pn:name="saa1099.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="Implementation"/>
|
||||
</file>
|
||||
<file xil_pn:name="audio_management.v" xil_pn:type="FILE_VERILOG">
|
||||
<association xil_pn:name="BehavioralSimulation"/>
|
||||
<association xil_pn:name="Implementation"/>
|
||||
</file>
|
||||
</files>
|
||||
|
||||
<properties>
|
||||
|
|
@ -107,11 +115,11 @@
|
|||
<property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Bus Delimiter" xil_pn:value="<>" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Case Implementation Style" xil_pn:value="Full-Parallel" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Change Device Speed To" xil_pn:value="-2" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-2" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
|
|
@ -129,7 +137,7 @@
|
|||
<property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="crono_samcoupe.wcfg" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="crono_asic_syncs.wcfg" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="DSP Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Device" xil_pn:value="xc6slx9" xil_pn:valueState="non-default"/>
|
||||
|
|
@ -322,8 +330,8 @@
|
|||
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/tb_samcoupe" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.tb_samcoupe" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/tb_asic" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.tb_asic" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
|
||||
|
|
@ -341,7 +349,7 @@
|
|||
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="SIMUL=1" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.tb_samcoupe" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.tb_asic" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
|
||||
|
|
@ -387,11 +395,11 @@
|
|||
<property xil_pn:name="Wakeup Clock spartan6" xil_pn:value="Startup Clock" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Watchdog Timer Value spartan6" xil_pn:value="0xFFFF" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="Write Timing Constraints" xil_pn:value="true" xil_pn:valueState="non-default"/>
|
||||
<!-- -->
|
||||
<!-- The following properties are for internal use only. These should not be modified.-->
|
||||
<!-- -->
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|tb_samcoupe" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Module|tb_asic" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_DesignName" xil_pn:value="samcoupe" xil_pn:valueState="non-default"/>
|
||||
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan6" xil_pn:valueState="default"/>
|
||||
<property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>
|
||||
|
|
|
|||
|
|
@ -51,10 +51,13 @@ module tb_asic;
|
|||
.data_enable_n(),
|
||||
.wait_n(),
|
||||
// RAM/ROM interface
|
||||
.ramaddr(),
|
||||
.vramaddr(),
|
||||
.cpuramaddr(),
|
||||
.data_from_ram(8'hAA),
|
||||
.ramwr_n(),
|
||||
.romcs_n(),
|
||||
.ramcs_n(),
|
||||
.asic_is_using_ram(),
|
||||
// audio I/O
|
||||
.ear(1'b0),
|
||||
.mic(),
|
||||
|
|
|
|||
|
|
@ -59,20 +59,22 @@ module tld_sam (
|
|||
assign stdn = 1'b0; // fijar norma PAL
|
||||
assign stdnb = 1'b1; // y conectamos reloj PAL
|
||||
|
||||
wire clk24, clk12, clk6;
|
||||
wire clk24, clk12, clk6, clk8;
|
||||
|
||||
relojes los_relojes (
|
||||
.CLK_IN1 (clk50mhz), // IN
|
||||
// Clock out ports
|
||||
.CLK_OUT1 (clk24), // OUT
|
||||
.CLK_OUT2 (clk12), // OUT
|
||||
.CLK_OUT3 (clk6) // OUT
|
||||
.CLK_OUT1 (clk24), // modulo multiplexor de SRAM
|
||||
.CLK_OUT2 (clk12), // ASIC
|
||||
.CLK_OUT3 (clk6), // CPU y teclado PS/2
|
||||
.CLK_OUT4 (clk8) // SAA1099 y DAC
|
||||
);
|
||||
|
||||
samcoupe maquina (
|
||||
.clk24(clk24),
|
||||
.clk12(clk12),
|
||||
.clk6(clk6),
|
||||
.clk8(clk8),
|
||||
.master_reset_n(1'b1), // esta señal es sólo para simulación
|
||||
// Video output
|
||||
.r(sam_r),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ module tv80_core (/*AUTOARG*/
|
|||
// Beginning of automatic inputs (from unused autoinst inputs)
|
||||
// End of automatics
|
||||
|
||||
parameter Mode = 1; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||
parameter Flag_C = 0;
|
||||
parameter Flag_N = 1;
|
||||
|
|
|
|||
|
|
@ -102,80 +102,65 @@ module tv80n (/*AUTOARG*/
|
|||
.intcycle_n (intcycle_n)
|
||||
);
|
||||
|
||||
always @*
|
||||
begin
|
||||
nxt_mreq_n = 1;
|
||||
nxt_rd_n = 1;
|
||||
nxt_iorq_n = 1;
|
||||
nxt_wr_n = 1;
|
||||
|
||||
if (mcycle[0])
|
||||
begin
|
||||
if (tstate[1] || tstate[2])
|
||||
begin
|
||||
nxt_rd_n = ~ intcycle_n;
|
||||
nxt_mreq_n = ~ intcycle_n;
|
||||
nxt_iorq_n = intcycle_n;
|
||||
end
|
||||
always @* begin
|
||||
nxt_mreq_n = 1;
|
||||
nxt_rd_n = 1;
|
||||
nxt_iorq_n = 1;
|
||||
nxt_wr_n = 1;
|
||||
|
||||
if (mcycle[0]) begin
|
||||
if (tstate[1] || tstate[2]) begin
|
||||
nxt_rd_n = ~ intcycle_n;
|
||||
nxt_mreq_n = ~ intcycle_n;
|
||||
nxt_iorq_n = intcycle_n;
|
||||
end
|
||||
end // if (mcycle[0])
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || tstate[2]) && !no_read && !write)
|
||||
begin
|
||||
nxt_rd_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
if (T2Write == 0)
|
||||
begin
|
||||
if (tstate[2] && write)
|
||||
begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
else begin
|
||||
if ((tstate[1] || tstate[2]) && !no_read && !write) begin
|
||||
nxt_rd_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
if (T2Write == 0) begin
|
||||
if (tstate[2] && write) begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || (tstate[2] && !wait_n)) && write)
|
||||
begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
end // else: !if(T2write == 0)
|
||||
end // else: !if(mcycle[0])
|
||||
else begin
|
||||
if ((tstate[1] || (tstate[2] && !wait_n)) && write) begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
end // else: !if(T2write == 0)
|
||||
end // else: !if(mcycle[0])
|
||||
end // always @ *
|
||||
|
||||
always @(negedge clk)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
rd_n <= #1 1'b1;
|
||||
wr_n <= #1 1'b1;
|
||||
iorq_n <= #1 1'b1;
|
||||
mreq_n <= #1 1'b1;
|
||||
always @(negedge clk) begin
|
||||
if (!reset_n) begin
|
||||
rd_n <= #1 1'b1;
|
||||
wr_n <= #1 1'b1;
|
||||
iorq_n <= #1 1'b1;
|
||||
mreq_n <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rd_n <= #1 nxt_rd_n;
|
||||
wr_n <= #1 nxt_wr_n;
|
||||
iorq_n <= #1 nxt_iorq_n;
|
||||
mreq_n <= #1 nxt_mreq_n;
|
||||
end // else: !if(!reset_n)
|
||||
else begin
|
||||
rd_n <= #1 nxt_rd_n;
|
||||
wr_n <= #1 nxt_wr_n;
|
||||
iorq_n <= #1 nxt_iorq_n;
|
||||
mreq_n <= #1 nxt_mreq_n;
|
||||
end // else: !if(!reset_n)
|
||||
end // always @ (posedge clk or negedge reset_n)
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
di_reg <= #1 0;
|
||||
always @(posedge clk) begin
|
||||
if (!reset_n) begin
|
||||
di_reg <= #1 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tstate[2] && wait_n == 1'b1)
|
||||
di_reg <= #1 di;
|
||||
end // else: !if(!reset_n)
|
||||
else begin
|
||||
if (tstate[2] && wait_n == 1'b1)
|
||||
di_reg <= #1 di;
|
||||
end // else: !if(!reset_n)
|
||||
end // always @ (posedge clk)
|
||||
|
||||
endmodule // t80n
|
||||
|
|
|
|||
Loading…
Reference in New Issue