change overall structure

This commit is contained in:
Raki
2021-11-12 11:26:52 +09:00
parent 1f7a4d2ac1
commit d7ecbab1ea
22 changed files with 2643 additions and 1984 deletions

View File

@@ -0,0 +1,690 @@
module BubSysROM_video
(
input wire i_EMU_MCLK,
input wire i_EMU_CLK18MNCEN_n,
output wire o_EMU_CLK9MPCEN_n, //REF_CLK9M
output wire o_EMU_CLK9MNCEN_n,
output wire o_EMU_CLK6MPCEN_n, //REF_CLK6M
output wire o_EMU_CLK6MNCEN_n,
input wire [15:0] i_CPU_ADDR,
input wire [16:0] i_CPU_DIN,
output wire [16:0] i_CPU_DOUT,
input wire i_CPU_RW,
input wire i_CPU_UDS_n,
input wire i_CPU_LDS_n,
input wire i_VZCS_n,
input wire i_HFLIP,
input wire i_VFLIP
);
///////////////////////////////////////////////////////////
////// CLOCK DIVIDER
////
/*
MCLK72 ################################################ or
MCLK36 |||||||||||||||||||||||||||||||||||||||||||||||| or
MCLK18 ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
18MNCEN ¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||¯¯||
0 1 2 3 4 5
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|
9MPCEN ¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||
9MNCEN ¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯¯¯||¯¯¯¯
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
6MPCEN ¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||
6MNCEN ¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯¯¯¯¯¯¯||¯¯¯¯
*/
reg [2:0] clock_counter_6 = 3'd5;
reg [3:0] cen_register = 4'b1111;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK18MNCEN_n)
begin
if(ref_clock_counter_6 < 3'd5)
begin
ref_clock_counter_6 <= ref_clock_counter_6 + 3'd1;
end
else
begin
ref_clock_counter_6 <= 3'd0;
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK18MNCEN_n)
begin
case(ref_clock_counter_12)
4'd0: cen_register <= 4'b0110;
4'd1: cen_register <= 4'b1001;
4'd2: cen_register <= 4'b0111;
4'd3: cen_register <= 4'b1010;
4'd4: cen_register <= 4'b0101;
4'd5: cen_register <= 4'b1011;
default: cen_register <= 4'b1111;
endcase
end
end
//ORed with 18M positive cen
assign o_EMU_CLK9MPCEN_n = cen_register[3] | i_EMU_CLK18MNCEN_n;
assign o_EMU_CLK9MNCEN_n = cen_register[2] | i_EMU_CLK18MNCEN_n;
assign o_EMU_CLK6MPCEN_n = cen_register[1] | i_EMU_CLK18MNCEN_n;
assign o_EMU_CLK6MNCEN_n = cen_register[0] | i_EMU_CLK18MNCEN_n;
//for reference
wire __REF_CLK9M = cen_register[3];
wire __REF_CLK6M = cen_register[1];
///////////////////////////////////////////////////////////
////// K005292
////
//
// asic seciton
//
wire HBLANK_n;
wire VBLANK_n;
wire VBLANKH_n;
wire ABS_256H;
wire ABS_n256H = ~ABS_256H;
wire ABS_128H;
wire ABS_128HA = (ABS_256H & ABS_128H) | (~ABS_256H & ABS_32H);
wire ABS_64H;
wire ABS_32H;
wire ABS_16H;
wire ABS_8H;
wire ABS_4H;
wire ABS_2H;
wire ABS_1H;
wire ABS_128V;
wire ABS_64V;
wire ABS_32V;
wire ABS_16V;
wire ABS_8V;
wire ABS_4V;
wire ABS_2V;
wire ABS_1V;
wire FLIP_n256H = ABS_n256H ^ i_HFLIP;
wire FLIP_128H;
wire FLIP_64H;
wire FLIP_32H;
wire FLIP_16H;
wire FLIP_8H;
wire FLIP_4H;
wire FLIP_2H;
wire FLIP_1H;
wire FLIP_128V;
wire FLIP_64V;
wire FLIP_32V;
wire FLIP_16V;
wire FLIP_8V;
wire FLIP_4V;
wire FLIP_2V;
wire FLIP_1V;
//declare K005292 core: this core does not have LS393 sprite code up counter
K005292 K005292_main
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_EMU_CLK6MPCEN_n (o_EMU_CLK6MPCEN_n ),
.i_MRST_n ( ),
.i_HFLIP ( ),
.i_VFLIP ( ),
.o_HBLANK_n ( ),
.o_VBLANK_n ( ),
.o_VBLANKH_n ( ), //VBLANK**
.o_ABS_256H (ABS_256H ),
.o_ABS_128H (ABS_128H ),
.o_ABS_64H (ABS_64H ),
.o_ABS_32H (ABS_32H ),
.o_ABS_16H (ABS_16H ),
.o_ABS_8H (ABS_8H ),
.o_ABS_4H (ABS_4H ),
.o_ABS_2H (ABS_2H ),
.o_ABS_1H (ABS_1H ),
.o_ABS_128V (ABS_128V ),
.o_ABS_64V (ABS_64V ),
.o_ABS_32V (ABS_32V ),
.o_ABS_16V (ABS_16V ),
.o_ABS_8V (ABS_8V ),
.o_ABS_4V (ABS_4V ),
.o_ABS_2V (ABS_2V ),
.o_ABS_1V (ABS_1V ),
.o_FLIP_128H (FLIP_128H ),
.o_FLIP_64H (FLIP_64H ),
.o_FLIP_32H (FLIP_32H ),
.o_FLIP_16H (FLIP_16H ),
.o_FLIP_8H (FLIP_8H ),
.o_FLIP_4H (FLIP_4H ),
.o_FLIP_2H (FLIP_2H ),
.o_FLIP_1H (FLIP_1H ),
.o_FLIP_128V (FLIP_128V ),
.o_FLIP_64V (FLIP_64V ),
.o_FLIP_32V (FLIP_32V ),
.o_FLIP_16V (FLIP_16V ),
.o_FLIP_8V (FLIP_8V ),
.o_FLIP_4V (FLIP_4V ),
.o_FLIP_2V (FLIP_2V ),
.o_FLIP_1V (FLIP_1V ),
.o_VCLK ( ),
.o_FRAMEPARITY ( ), //256V
.o_DMA_n ( ),
.o_VSYNC_n ( ),
.o_CSYNC_n ( )
);
//
// MEMORY TIMING GENERATOR SECTION
//
/*
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
---(511)---|----(0)----|----(1)----|----(2)----|
TIME1 ___________________|¯¯¯|___________________|¯¯¯|
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|
CHAMPX ¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯
VRTIME ¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯
OBJCLRWE¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
BUFWE ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
BUFRAS ___________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|____
dl-ras ____________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|___
*/
//timing singals
wire TIME1; //SCROLLRAM/OBJRAM read latch enable(active high)
wire TIME2; //SCROLLRAM/OBJRAM data write enable(active low)
wire VRTIME; //Video Read TIME
wire CHAMPX; //CHAracter MultiPleXer
wire OBJCLRWE; //OBJect CLeaR Write Enable
//17H LS74A(1HF)
reg DFF_17H_A; //1HF
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
DFF_17H_A <= ABS_1H;
end
end
//15H LS164
reg [3:0] SR_15H; //QA QB QC QD
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK18MNCEN_n)
begin
SR_15H[3] <= DFF_17H_A;
SR_15H[2:0] <= SR_15H[3:1];
end
end
assign TIME1 = ~(~DFF_17H_A | __REF_CLK6M); //16H LS02 NOR
assign TIME2 = ~(DFF_17H_A & SR_15H[2]); //15G LS00 NAND
assign VRTIME = ~(DFF_17H_A & ~SR_15H[3]); //15G LS00 NAND
assign CHAMPX = SR_15H[2] | SR_15H[1]; //CHAMPX+CHAMPX1 14H LS32 OR
assign OBJCLRWE = SR_15H[2] | ~SR_15H[1]; //14H LS32 OR
//
// VIDEO TIMING GENERATOR SECTION
//
//timing singals
wire OBJRW; //switches mux between active display+buffer clear/005295 write
wire OBJCLR; //fix mux output as 0 when clearing the buffer by writing 0s
wire BLK; //LS09 driver disable
//19H LS74A
reg DFF_19H_A;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
if({ABS_8H, ABS_4H, ABS_2H, ABS_1H} == 4'd15) //posedge of 16H
begin
DFF_19H_A <= ~(HBLANK_n & VBLANKH_n); //15G LS00 NAND
end
end
end
//19H LS74B
reg DFF_19H_B;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MNCEN_n) //negedge cen
begin
if(ABS_1H == 1'b0) //every EVEN pixel
begin
DFF_19H_B <= DFF_19H_A;
end
end
end
//20H LS74B
reg DFF_20H_B;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
if({ABS_2H, ABS_1H} == 2'd3) //posedge of 4H
begin
DFF_20H_B <= DFF_19H_A;
end
end
end
//20H LS74B
reg DFF_20H_A;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
DFF_20H_A <= DFF_20H_B;
end
end
//17A LS74A
reg DFF_17A_A;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
DFF_17A_A <= ~DFF_20H_A & VBLANK_n; //21H LS08 AND
end
end
assign OBJRW = DFF_19H_B;
assign OBJCLR = ~DFF_19H_B;
assign BLK = DFF_17A_A;
///////////////////////////////////////////////////////////
////// K005291
////
//
// scrollram seciton
//
/*
Note: TM-A is scroll1 in MAME
TM-B is scroll2 in MAME
FETCHES HSCROLL(1 PIXEL ROW) VALUE WHEN VCLK = 1
MCLK 0 1 2 3 4 5 0 1 2 3 4 5
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|
>SRAM DOUT >SRAM DOUT >SRAM DOUT >SRAM DOUT SRAM async access speed >150ns (2128-15 on every PCB)
TIME1 ___________________|¯¯¯|___________________|¯¯¯|____________
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
VCLK ___________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
ADDR |-------(TM-A LO)-------|-------(TM-A HI)-------|
DEVICE |---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|
| TM-A LO | | TM-A HI |
FETCHES VSCROLL(8 PIXEL COLUMN) VALUE WHEN VCLK = 0
(TM-A for 4H = 0, TM-B for 4H = 1)
1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|
TIME1 ___________________|¯¯¯|___________________|¯¯¯|___________________|¯¯¯|___________________|¯¯¯|____________
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
VCLK ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
SCRLATCH¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|
SCRADDR --(TM-A)---|--------------------(TM-B)---------------------|--------------------(TM-A)---------------------|
DEVICE ---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|
VRAMADDR--(TM-B)---|--------------------(TM-A)---------------------|--------------------(TM-B)---------------------|
t0 t1 t2
0. HSCROLL values for TM-A and TM-B are latched when VCLK = 1
t0
1. MUX provides TM-A VSCROLL address when 4H = 0 & VCLK = 0
2. 005291 latches TM-A VSCROLL value at posedge of ~(1H & 2H)
3. Then TM-A VSCROLL value will be valid during next 4px-cycle
4. In this next 4px-cycle, 005291 provides previously latched(at VCLK = 0) TM-A HSCROLL value
t1
1. Again, 005291 latches TM-A VSCROLL value at posedge of ~(1H & 2H) since MUX provided TM-B VSCROLL address
2. Then TM-B VSCROLL value will be valid during next 4px-cycle
3. In this next 4px-cycle, 005291 provides previously latched(at VCLK = 0) TM-B HSCROLL value
*/
//make scrollram address
wire [10:0] scrollval_addr;
assign scrollval_addr = (~i_VCLK == 1'b0) ?
{1'b0, ABS_4H, ABS_2H, FLIP_128V, FLIP_64V, FLIP_32V, FLIP_16V, FLIP_8V, FLIP_4V, FLIP_2V, FLIP_1V} : //HORIZONTAL SCROLL
{1'b1, 1'b1, 1'b1, 1'b1, ABS_4H,FLIP_n256H, FLIP_128H, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H}; //VERTICAL SCROLL
wire [10:0] scrollram_addr;
assign scrollram_addr = (~ABS_1H == 1'b0) ?
scrollval_addr :
i_CPU_ADDR;
//make scrollram wr signal
wire scrollram_wr = (i_VZCS_n | i_CPU_RW | i_CPU_LDS_n | TIME2);
//declare SCROLLRAM
wire [7:0] scrollram_dout;
SRAM2k8 SCROLLRAM_LOW
(
.i_MCLK (i_EMU_MCLK ),
.i_ADDR (scrollram_addr ),
.i_DIN (i_CPU_DIN[7:0] ),
.o_DOUT (scrollram_dout ),
.i_WR_n (scrollram_wr ),
.i_RD_n (1'b0 )
);
//declare CPU side latch
wire [7:0] scrollram_cpulatch_q;
LOGIC373 SCROLLRAM_CPULATCH
(
.i_MCLK (i_EMU_MCLK ),
.i_D (scrollram_dout ),
.o_Q (scrollram_readlatch_q ),
.i_LE_n (TIME1 )
);
//
// asic seciton
//
wire [11:0] vram_addr;
wire [2:0] line_addr;
//declare K005291 core: requires clock
K005291 K005291_main
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_EMU_CLK6MPCEN_n (o_EMU_CLK6MPCEN_n ),
.i_HFLIP ( ),
.i_VFLIP ( ),
.i_ABS_n256H (ABS_n256H ),
.i_ABS_128HA (ABS_128HA ),
.i_ABS_64H (ABS_64H ),
.i_ABS_32H (ABS_32H ),
.i_ABS_16H (ABS_16H ),
.i_ABS_8H (ABS_8H ),
.i_ABS_4H (ABS_4H ),
.i_ABS_2H (ABS_2H ),
.i_ABS_1H (ABS_1H ),
.i_ABS_128V (ABS_128V ),
.i_ABS_64V (ABS_64V ),
.i_ABS_32V (ABS_32V ),
.i_ABS_16V (ABS_16V ),
.i_ABS_8V (ABS_8V ),
.i_ABS_4V (ABS_4V ),
.i_ABS_2V (ABS_2V ),
.i_ABS_1V (ABS_1V ),
.i_VCLK ( ),
.i_CPUADDR ( ),
.i_GFXDATA ( ),
.o_TILELINEADDR (line_addr ),
.o_VRAMADDR (vram_addr ),
.o_SHIFTA1 ( ),
.o_SHIFTA2 ( ),
.o_SHIFTB ( )
);
//
// VRAM1+2 section
//
/*
MCLK
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
PIXEL ----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|
/DTACK ¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
>SRAM CPU DIN >SRAM GFX DOUT >SRAM CPU DOUT >SRAM GFX DOUT SRAM async access speed 100ns (TC5533-P on every PCB)
VRTIME ¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 6264 CE2 is always 1 in cpu access cycle
DEVICE |---------(CPU)---------|---------(GFX)---------|---------(CPU)---------|---------(GFX)---------|
|(RD VALID)-| |(RD VALID)-| ext. gates allow RD during pixel 0 and 1 cycles
|WRVAL| |WRVAL| ext. gates allow WR during pixel 0 cycle
| VRAM ADDR TM-A | VRAM ADDR TM-B |
>VRAM ADDR TM-A latched by LS273 at /2H
>CHARRAM TM-A line data latched
*/
//make vram wr signal
wire vram1h_wr = (i_VCS1_n | i_CPU_RW | i_CPU_UDS_n | ABS_1H | ABS_2H); //pixel 0 and 4
wire vram1l_wr = (i_VCS1_n | i_CPU_RW | i_CPU_LDS_n | ABS_1H | ABS_2H);
wire vram2l_wr = (i_VCS2_n | i_CPU_RW | i_CPU_LDS_n | ABS_1H | ABS_2H);
//declare vram1
wire [15:0] vram1_dout;
SRAM4k8 VRAM1_HIGH
(
.i_MCLK (i_EMU_MCLK ),
.i_ADDR (vram_addr ),
.i_DIN (i_CPU_DIN[15:8] ),
.o_DOUT (vram1_dout[15:8] ),
.i_WR_n (vram1h_wr ),
.i_RD_n (VRTIME )
);
SRAM4k8 VRAM1_LOW
(
.i_MCLK (i_EMU_MCLK ),
.i_ADDR (vram_addr ),
.i_DIN (i_CPU_DIN[7:0] ),
.o_DOUT (vram1_dout[7:0] ),
.i_WR_n (vram1l_wr ),
.i_RD_n (VRTIME )
);
//declare vram2
wire [7:0] vram2_dout;
SRAM4k8 VRAM2_LOW
(
.i_MCLK (i_EMU_MCLK ),
.i_ADDR (vram_addr ),
.i_DIN (i_CPU_DIN[7:0] ),
.o_DOUT (vram2_dout ),
.i_WR_n (vram2l_wr ),
.i_RD_n (VRTIME )
);
///////////////////////////////////////////////////////////
////// CHARRAM
////
/*
MCLK 1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
PIXEL ----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|
/DTACK ¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
>row >column >row >column
CHAMPX1 ¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/RAS ___________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|________________ 15ns(LS14) delayed
/CAS ________________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|___________ 15ns*4(LS14) + 25ns(220pF) = about 85ns delayed
>DRAM CPU/REFRESH >DRAM GFX DOUT >DRAM CPU/REFRESH >DRAM GFX DOU DRAM async access speed 150ns (TMS4416)
Automatically refreshes ROW ADDRESS during CPU/HV counter access cycle
DEVICE |---------(CPU)---------|---------(GFX)---------|---------(CPU)---------|---------(GFX)---------|
LATCHED CPU WR ¯¯¯¯¯¯¯¯¯¯¯¯|_______________________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|(WR VALID)-| |(WR VALID)-|
|(RD VALID)-| |(RD VALID)-|
| CHARRAM ADDR TM-A | CHARRAM ADDR TM-B |
>CHARRAM TM-A data latched by K005290
>CHARRAM data TM-B latched by K005290
*/
//
// VRAM1 tile code DFF
//
reg [10:0] tile_code;
reg VVFF;
always @(posedge i_EMU_MCLK)
begin
if(!o_EMU_CLK6MPCEN_n)
begin
if({ABS_4H, ABS_2H, ABS_1H} == 3'd3 || {ABS_4H, ABS_2H, ABS_1H} == 3'd7) //posedge of /2H
begin
tile_code <= vram1_dout[10:0];
VVFF <= vram1_dout[11];
end
end
end
//
// tile address
//
wire [8:0] VCA;
assign VCA = (CHAMPX == 1'b0) ?
{ //CAS
1'b1,
tile_code[10],
tile_code[9],
tile_code[8],
tile_code[7],
tile_code[6],
tile_code[5],
1'b1
} :
{ //RAS
tile_code[4],
tile_code[3],
tile_code[2],
tile_code[1],
tile_code[0],
line_addr[2] ^ VVFF,
line_addr[1] ^ VVFF,
line_addr[0] ^ VVFF
};
wire [8:0] gfx_addr;
assign gfx_addr = () ? VCA : OCA;
wire [8:0] cpu_addr;
assign cpu_addr = (CHAMPX == 1'b0) ?
{ //CAS
1'b1, //HIGH
i_CPUADDR[14], //A15
i_CPUADDR[13], //A14
i_CPUADDR[12], //A13
i_CPUADDR[11], //A12
i_CPUADDR[10], //A11
i_CPUADDR[9], //A10
1'b1 //HIGH
} :
{ //RAS
i_CPUADDR[8], //A9
i_CPUADDR[7], //A8
i_CPUADDR[6], //A7
i_CPUADDR[5], //A6
i_CPUADDR[4], //A5
i_CPUADDR[3], //A4
i_CPUADDR[2], //A3
i_CPUADDR[1] //A2
};
endmodule

View File

@@ -0,0 +1,277 @@
/*
K005290 TILEMAP SHIFT REGISTER ARRAY
*/
module K005290
(
//emulator
input wire i_EMU_MCLK,
input wire i_EMU_CLK6MPCEN_n,
//pixel data
input wire [31:0] i_GFXDATA,
//hcounter
input wire i_ABS_n4H,
input wire i_ABS_2H,
//flips
input wire i_A_FLIP,
input wire i_B_FLIP,
//sr mode
input wire [1:0] i_A_MODE,
input wire [1:0] i_B_MODE,
//pixel output
output reg [3:0] o_A_PIXEL,
output reg [3:0] o_B_PIXEL,
//pixel transparent flag
output wire o_A_TRN_n,
output wire o_B_TRN_n
);
///////////////////////////////////////////////////////////
////// PIXEL DATA LATCH
////
//
// clock enable generator: there's no 1H input
//
/*
pixel 0 1 2 3 4 5 6 7
1H _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
2H ___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
2H-dl _____|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯
/4H ¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|
4H _______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯|_______|
*/
reg ABS_2H_dl;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
ABS_2H_dl <= i_ABS_2H;
end
end
wire pixel3_n = i_ABS_2H & ABS_2H_dl & i_ABS_n4H;
wire pixel7_n = i_ABS_2H & ABS_2H_dl & ~i_ABS_n4H;
//
// pixel latches
//
/*
LEFT RIGHT
PIXEL | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
DRAM A B C D E F G H
*/
reg [31:0] A_LINELATCH;
reg [31:0] B_LINELATCH;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(!pixel7_n) //posedge of px7
begin
A_LINELATCH <= i_GFXDATA;
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(!pixel3_n) //posedge of px3
begin
B_LINELATCH <= i_GFXDATA;
end
end
end
///////////////////////////////////////////////////////////
////// PIXEL SHIFT REGISTER
////
/*
74LS194
S0 S1
0 0 : hold
0 1 : shift right(Qa->Qd) : flipped
1 0 : shift left(Qd->Qa) : normal
1 1 : parallel load
*/
//
// TM-A shift register
//
reg [3:0] A_PIXEL0 = 4'h0;
reg [3:0] A_PIXEL1 = 4'h0;
reg [3:0] A_PIXEL2 = 4'h0;
reg [3:0] A_PIXEL3 = 4'h0;
reg [3:0] A_PIXEL4 = 4'h0;
reg [3:0] A_PIXEL5 = 4'h0;
reg [3:0] A_PIXEL6 = 4'h0;
reg [3:0] A_PIXEL7 = 4'h0;
reg [3:0] A_PIXEL_DELAY1;
reg [3:0] A_PIXEL_DELAY2;
reg [3:0] A_PIXEL_DELAY3;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
case(i_A_MODE)
2'b00: begin end
2'b01: begin
if(i_A_FLIP == 1'b0) begin
A_PIXEL_DELAY1 <= 4'h0; //displays black only
end
else begin //shift reversed direction(right)
A_PIXEL0 <= 4'h0;
A_PIXEL1 <= A_PIXEL0;
A_PIXEL2 <= A_PIXEL1;
A_PIXEL3 <= A_PIXEL2;
A_PIXEL4 <= A_PIXEL3;
A_PIXEL5 <= A_PIXEL4;
A_PIXEL6 <= A_PIXEL5;
A_PIXEL7 <= A_PIXEL6;
A_PIXEL_DELAY1 <= A_PIXEL7;
end
end
2'b10: begin
if(i_A_FLIP == 1'b0) begin //shift normally
A_PIXEL_DELAY1 <= A_PIXEL0;
A_PIXEL0 <= A_PIXEL1;
A_PIXEL1 <= A_PIXEL2;
A_PIXEL2 <= A_PIXEL3;
A_PIXEL3 <= A_PIXEL4;
A_PIXEL4 <= A_PIXEL5;
A_PIXEL5 <= A_PIXEL6;
A_PIXEL6 <= A_PIXEL7;
A_PIXEL7 <= 4'h0;
end
else begin //flip
A_PIXEL_DELAY1 <= 4'h0; //displays black only
end
end
2'b11: begin
A_PIXEL0 <= A_LINELATCH[31:28];
A_PIXEL1 <= A_LINELATCH[27:24];
A_PIXEL2 <= A_LINELATCH[23:20];
A_PIXEL3 <= A_LINELATCH[19:16];
A_PIXEL4 <= A_LINELATCH[15:12];
A_PIXEL5 <= A_LINELATCH[11:8];
A_PIXEL6 <= A_LINELATCH[7:4];
A_PIXEL7 <= A_LINELATCH[3:0];
end
endcase
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
A_PIXEL_DELAY2 <= A_PIXEL_DELAY1;
A_PIXEL_DELAY3 <= A_PIXEL_DELAY2;
o_A_PIXEL <= A_PIXEL_DELAY3;
end
end
assign o_A_TRN_n = o_A_PIXEL[3] | o_A_PIXEL[2] | o_A_PIXEL[1] | o_A_PIXEL[0];
//
// TM-B shift register
//
reg [3:0] B_PIXEL0 = 4'h0;
reg [3:0] B_PIXEL1 = 4'h0;
reg [3:0] B_PIXEL2 = 4'h0;
reg [3:0] B_PIXEL3 = 4'h0;
reg [3:0] B_PIXEL4 = 4'h0;
reg [3:0] B_PIXEL5 = 4'h0;
reg [3:0] B_PIXEL6 = 4'h0;
reg [3:0] B_PIXEL7 = 4'h0;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
case(i_B_MODE)
2'b00: begin end
2'b01: begin
if(i_B_FLIP == 1'b0) begin
o_B_PIXEL <= 4'h0; //displays black only
end
else begin //shift reversed direction(right)
B_PIXEL0 <= 4'h0;
B_PIXEL1 <= B_PIXEL0;
B_PIXEL2 <= B_PIXEL1;
B_PIXEL3 <= B_PIXEL2;
B_PIXEL4 <= B_PIXEL3;
B_PIXEL5 <= B_PIXEL4;
B_PIXEL6 <= B_PIXEL5;
B_PIXEL7 <= B_PIXEL6;
o_B_PIXEL <= B_PIXEL7;
end
end
2'b10: begin
if(i_B_FLIP == 1'b0) begin //shift normally
o_B_PIXEL <= B_PIXEL0;
B_PIXEL0 <= B_PIXEL1;
B_PIXEL1 <= B_PIXEL2;
B_PIXEL2 <= B_PIXEL3;
B_PIXEL3 <= B_PIXEL4;
B_PIXEL4 <= B_PIXEL5;
B_PIXEL5 <= B_PIXEL6;
B_PIXEL6 <= B_PIXEL7;
B_PIXEL7 <= 4'h0;
end
else begin //flip
o_B_PIXEL <= 4'h0; //displays black only
end
end
2'b11: begin
B_PIXEL0 <= B_LINELATCH[31:28];
B_PIXEL1 <= B_LINELATCH[27:24];
B_PIXEL2 <= B_LINELATCH[23:20];
B_PIXEL3 <= B_LINELATCH[19:16];
B_PIXEL4 <= B_LINELATCH[15:12];
B_PIXEL5 <= B_LINELATCH[11:8];
B_PIXEL6 <= B_LINELATCH[7:4];
B_PIXEL7 <= B_LINELATCH[3:0];
end
endcase
end
end
assign o_B_TRN_n = o_B_PIXEL[3] | o_B_PIXEL[2] | o_B_PIXEL[1] | o_B_PIXEL[0];
endmodule

View File

@@ -0,0 +1,157 @@
/*
K005291 TILEMAP GENERATOR
*/
module K005291
(
//emulator
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
input wire i_EMU_CLK6MPCEN_n,
//CPU flip
input wire i_HFLIP,
input wire i_VFLIP,
//HV counters
input wire i_ABS_n256H,
input wire i_ABS_128HA,
input wire i_ABS_64H,
input wire i_ABS_32H,
input wire i_ABS_16H,
input wire i_ABS_8H,
input wire i_ABS_4H,
input wire i_ABS_2H,
input wire i_ABS_1H,
input wire i_ABS_128V,
input wire i_ABS_64V,
input wire i_ABS_32V,
input wire i_ABS_16V,
input wire i_ABS_8V,
input wire i_ABS_4V,
input wire i_ABS_2V,
input wire i_ABS_1V,
input wire i_VCLK,
//CPU address/GFX data bus
input wire [11:0] i_CPUADDR,
input wire [7:0] i_GFXDATA,
//to CHARRAM
output reg [2:0] o_TILELINEADDR,
//to VRAM1+2
output wire [11:0] o_VRAMADDR,
output wire o_SHIFTA1,
output wire o_SHIFTA2,
output wire o_SHIFTB
);
wire ABS_4H = i_ABS_4H;
wire ABS_2H = i_ABS_2H;
wire ABS_1H = i_ABS_1H;
wire FLIP_n256H = i_ABS_n256H ^ i_HFLIP;
wire FLIP_128HA = i_ABS_128HA ^ i_HFLIP;
wire FLIP_64H = i_ABS_64H ^ i_HFLIP;
wire FLIP_32H = i_ABS_32H ^ i_HFLIP;
wire FLIP_16H = i_ABS_16H ^ i_HFLIP;
wire FLIP_8H = i_ABS_8H ^ i_HFLIP;
wire FLIP_4H = i_ABS_4H ^ i_HFLIP;
wire FLIP_2H = i_ABS_2H ^ i_HFLIP;
wire FLIP_1H = i_ABS_1H ^ i_HFLIP;
wire FLIP_128V = i_ABS_128V ^ i_VFLIP;
wire FLIP_64V = i_ABS_64V ^ i_VFLIP;
wire FLIP_32V = i_ABS_32V ^ i_VFLIP;
wire FLIP_16V = i_ABS_16V ^ i_VFLIP;
wire FLIP_8V = i_ABS_8V ^ i_VFLIP;
wire FLIP_4V = i_ABS_4V ^ i_VFLIP;
wire FLIP_2V = i_ABS_2V ^ i_VFLIP;
wire FLIP_1V = i_ABS_1V ^ i_VFLIP;
///////////////////////////////////////////////////////////
////// TILEMAP SCROLL
////
//
// HSCROLL
//
reg [8:0] TMA_HSCROLL_VALUE = 9'h1F;
reg [8:0] TMB_HSCROLL_VALUE = 9'h1F;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(i_VCLK)
begin
case({ABS_4H, ABS_2H, ABS_1H})
3'd1: begin TMA_HSCROLL_VALUE[7:0] <= i_GFXDATA; end //latch TM-A lower bits at px1
3'd3: begin TMA_HSCROLL_VALUE[8] <= i_GFXDATA[0]; end //latch TM-B high bit at px3
3'd5: begin TMB_HSCROLL_VALUE[7:0] <= i_GFXDATA; end //latch TM-A lower bits at px5
3'd7: begin TMB_HSCROLL_VALUE[8] <= i_GFXDATA[0]; end //latch TM-B high bit at px7
default: begin end
endcase
end
end
end
//vram address
wire [5:0] horizontal_tile_addr; //6 bit: 64 horizontal tiles(512 horizontal pixels)
assign horizontal_tile_addr = (ABS_4H == 1'b0) ?
TMA_HSCROLL_VALUE[8:3] + {FLIP_n256H, FLIP_128HA, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H} :
TMB_HSCROLL_VALUE[8:3] + {FLIP_n256H, FLIP_128HA, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H};
//shift
assign o_SHIFTA1 = (TMA_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd7) ? 1'b0 : 1'b1;
assign o_SHIFTA2 = (TMA_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd3) ? 1'b0 : 1'b1;
assign o_SHIFTB = (TMB_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd3) ? 1'b0 : 1'b1;
//
// VSCROLL
//
reg [7:0] TMAB_VSCROLL_VALUE = 8'hF;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
case({ABS_4H, ABS_2H, ABS_1H})
3'd3: begin TMAB_VSCROLL_VALUE <= i_GFXDATA; //latch TM-B second at px3
o_TILELINEADDR <= TMAB_VSCROLL_VALUE[2:0] + {FLIP_4V, FLIP_2V, FLIP_1V}; end
3'd7: begin TMAB_VSCROLL_VALUE <= i_GFXDATA; //latch TM-A first at px7
o_TILELINEADDR <= TMAB_VSCROLL_VALUE[2:0] + {FLIP_4V, FLIP_2V, FLIP_1V}; end
default: begin end
endcase
end
end
//pixel 3: get TM-B vscroll value
//pixel 7: get TM-A vscroll value/update TM-B line address
//pixel 3: get TM-B vscroll value/update TM-A line address
//vram address
wire [7:0] vertical_tile_addr; //[7:3] 5 bit: 32 vertical tiles(512 horizontal pixels)
assign vertical_tile_addr = TMAB_VSCROLL_VALUE + {FLIP_128V, FLIP_64V, FLIP_32V, FLIP_16V, FLIP_8V, FLIP_4V, FLIP_2V, FLIP_1V};
///////////////////////////////////////////////////////////
////// VRAM TILE ADDRESS
////
assign o_VRAMADDR = (ABS_2H == 1'b0) ?
i_CPUADDR :
{ABS_4H, vertical_tile_addr[7:3], horizontal_tile_addr};
endmodule

View File

@@ -0,0 +1,213 @@
/*
K005292 VIDEO TIMING GENERATOR
*/
module K005292
(
input wire i_EMU_MCLK,
input wire i_EMU_CLK6MPCEN_n,
input wire i_MRST_n,
input wire i_HFLIP,
input wire i_VFLIP,
output wire o_HBLANK_n,
output reg o_VBLANK_n = 1'b1,
output reg o_VBLANKH_n = 1'b1,
output wire o_ABS_256H,
output wire o_ABS_128H,
output wire o_ABS_64H,
output wire o_ABS_32H,
output wire o_ABS_16H,
output wire o_ABS_8H,
output wire o_ABS_4H,
output wire o_ABS_2H,
output wire o_ABS_1H,
output wire o_ABS_128V,
output wire o_ABS_64V,
output wire o_ABS_32V,
output wire o_ABS_16V,
output wire o_ABS_8V,
output wire o_ABS_4V,
output wire o_ABS_2V,
output wire o_ABS_1V,
output wire o_FLIP_128H,
output wire o_FLIP_64H,
output wire o_FLIP_32H,
output wire o_FLIP_16H,
output wire o_FLIP_8H,
output wire o_FLIP_4H,
output wire o_FLIP_2H,
output wire o_FLIP_1H,
output wire o_FLIP_128V,
output wire o_FLIP_64V,
output wire o_FLIP_32V,
output wire o_FLIP_16V,
output wire o_FLIP_8V,
output wire o_FLIP_4V,
output wire o_FLIP_2V,
output wire o_FLIP_1V,
output reg o_VCLK = 1'b0,
output reg o_FRAMEPARITY = 1'b0,
output reg o_DMA_n = 1'b1,
output wire o_VSYNC_n,
output wire o_CSYNC_n
);
///////////////////////////////////////////////////////////
////// PIXEL COUNTER/BLANKING/SYNC/DMA
////
reg [8:0] horizontal_counter = 9'd511;
assign {
o_ABS_256H,
o_ABS_128H,
o_ABS_64H,
o_ABS_32H,
o_ABS_16H,
o_ABS_8H,
o_ABS_4H,
o_ABS_2H,
o_ABS_1H
} = horizontal_counter;
assign {
o_FLIP_128H,
o_FLIP_64H,
o_FLIP_32H,
o_FLIP_16H,
o_FLIP_8H,
o_FLIP_4H,
o_FLIP_2H,
o_FLIP_1H
} = horizontal_counter[7:0] ^ {8{i_HFLIP}};
assign o_HBLANK_n = horizontal_counter[8];
reg [8:0] vertical_counter = 8'd248;
assign {
o_ABS_128V,
o_ABS_64V,
o_ABS_32V,
o_ABS_16V,
o_ABS_8V,
o_ABS_4V,
o_ABS_2V,
o_ABS_1V
} = vertical_counter;
assign {
o_FLIP_128V,
o_FLIP_64V,
o_FLIP_32V,
o_FLIP_16V,
o_FLIP_8V,
o_FLIP_4V,
o_FLIP_2V,
o_FLIP_1V
} = vertical_counter ^ {8{i_VFLIP}};
assign o_VSYNC_n = vertical_counter[8];
always @(posedge i_EMU_MCLK or negedge i_MRST_n)
begin
if(!i_MRST_n) //asynchronous reset
begin
horizontal_counter <= 9'd128;
vertical_counter <= 8'd248;
o_VBLANK_n <= 1'b0;
o_VBLANKH_n <= 1'b0;
o_FRAMEPARITY <= 1'b0;
o_DMA_n <= 1'b1;
end
else
begin //count up
if(!i_EMU_CLK6MPCEN_n)
begin
if(horizontal_counter < 9'd511) //h count up
begin
if(horizontal_counter == 9'd175) //v count up
begin
if(vertical_counter < 9'd511)
begin
//VBLANK
if(vertical_counter > 9'd495 || vertical_counter < 9'd271)
begin
o_VBLANK_n <= 1'b0;
end
else
begin
o_VBLANK_n <= 1'b1;
end
//VBLANK**
if(vertical_counter > 9'd247 && vertical_counter < 9'd271)
begin
o_VBLANKH_n <= 1'b0;
end
else
begin
o_VBLANKH_n <= 1'b1;
end
//256V
if(vertical_counter == 9'd495) //flip parity value
begin
o_FRAMEPARITY <= ~o_FRAMEPARITY;
end
//DMA
if(vertical_counter > 9'd478 && vertical_counter < 9'd496)
begin
o_DMA_n <= 1'b0;
end
else
begin
o_DMA_n <= 1'b1;
end
vertical_counter <= vertical_counter + 9'd1;
end
else
begin
vertical_counter <= 9'd248;
end
end
if(horizontal_counter > 9'd174 && horizontal_counter < 9'd207)
begin
o_VCLK <= 1'b1;
end
else
begin
o_VCLK <= 1'b0;
end
horizontal_counter <= horizontal_counter + 9'd1;
end
else //h loop
begin
horizontal_counter <= 9'd128;
end
end
end
end
///////////////////////////////////////////////////////////
////// SYNC GENERATOR
////
assign o_VSYNC_n = vertical_counter[8];
assign o_CSYNC_n = o_VSYNC_n & ~o_VCLK;
endmodule

View File

@@ -0,0 +1,603 @@
/*
K005293 PRIORITY HANDLER
*/
module K005293
(
//emulator
input wire i_EMU_MCLK,
input wire i_EMU_CLK6MPCEN_n,
//flip
input wire i_HFLIP,
//clocked shift
input wire i_SHIFTA1,
input wire i_SHIFTA2,
input wire i_SHIFTB,
//timings
input wire i_ABS_n1H,
input wire i_ABS_n6n7H,
input wire i_ABS_n2n3H,
//pixel input
input wire [3:0] i_A_PIXEL,
input wire [3:0] i_B_PIXEL,
//pixel transparent flag
input wire i_A_TRN_n,
input wire i_B_TRN_n,
//tile properties
input wire i_VHFF,
input wire [6:0] i_VC,
input wire [3:0] i_PR,
//sprite pixels
input wire [15:0] i_OBJBUF_DATA,
//delayed flips
output wire o_A_FLIP,
output wire o_B_FLIP,
//palette code
output reg [10:0] o_CD
);
///////////////////////////////////////////////////////////
////// PROPERTY DATA SHIFTER
////
/*
if SCROLL = 0
i_ABS_n2n3H i_ABS_n6n7H i_ABS_n2n3H i_ABS_n6n7H
i_SHIFTA1 i_SHIFTA2
i_SHIFTB
TM-A DELAY1 -> DELAY2 -> DELAY3 -> DELAY4
TM-B DELAY1 -> DELAY2 -> DELAY3
*/
//
// TM-A
//
//PR4, PR3, PR2, PR1, VHFF, VC6 ... VC0
reg [11:0] A_PROPERTY_DELAY1;
reg [11:0] A_PROPERTY_DELAY2;
reg [11:0] A_PROPERTY_DELAY3;
reg [11:0] A_PROPERTY_DELAY4;
wire [3:0] a_pr = A_PROPERTY_DELAY4[11:8];
wire [6:0] a_palette = A_PROPERTY_DELAY4[6:0];
assign o_A_FLIP = A_PROPERTY_DELAY4[7];
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if((i_ABS_n2n3H || i_ABS_n1H) == 1'b0) //posedge of pixel 3
begin
A_PROPERTY_DELAY1 <= {i_PR, i_VHFF, i_VC};
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if((i_ABS_n6n7H || i_ABS_n1H) == 1'b0) //posedge of pixel 7
begin
A_PROPERTY_DELAY2 <= A_PROPERTY_DELAY1;
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(i_SHIFTA1 == 1'b0) //posedge of pixel 7
begin
A_PROPERTY_DELAY3 <= A_PROPERTY_DELAY2;
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(i_SHIFTA2 == 1'b0) //posedge of pixel 7
begin
A_PROPERTY_DELAY4 <= A_PROPERTY_DELAY3;
end
end
end
//
// TM-B
//
//PR2, PR1, VHFF, VC6 ... VC0
//note that PR3,2 bits of TM-B are always ignored: verified with a real hardware by brute-force
reg [9:0] B_PROPERTY_DELAY1;
reg [9:0] B_PROPERTY_DELAY2;
reg [9:0] B_PROPERTY_DELAY3;
wire [2:0] b_pr = B_PROPERTY_DELAY3[9:8];
wire [6:0] b_palette = B_PROPERTY_DELAY3[6:0];
assign o_B_FLIP = B_PROPERTY_DELAY3[7];
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if((i_ABS_n6n7H || i_ABS_n1H) == 1'b0) //posedge of pixel 3
begin
B_PROPERTY_DELAY1 <= {i_PR[1:0], i_VHFF, i_VC};
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if((i_ABS_n2n3H || i_ABS_n1H) == 1'b0) //posedge of pixel 7
begin
B_PROPERTY_DELAY2 <= B_PROPERTY_DELAY1;
end
end
end
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(i_SHIFTB == 1'b0) //posedge of pixel 7
begin
B_PROPERTY_DELAY3 <= B_PROPERTY_DELAY2;
end
end
end
///////////////////////////////////////////////////////////
////// SPRITE PIXEL LATCH
////
reg [7:0] OBJ_PIXEL0;
reg [7:0] OBJ_PIXEL1;
wire [7:0] obj_pixel;
wire obj_trn_n = (obj_pixel[3] | obj_pixel[2] | obj_pixel[1] | obj_pixel[0]);
assign obj_pixel = ((~i_ABS_n1H ^ i_HFLIP) == 1'b0) ? OBJ_PIXEL0 : OBJ_PIXEL1;
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(i_ABS_n1H == 1'b0) //posedge of pixel 7
begin
OBJ_PIXEL1 <= i_OBJBUF_DATA[15:8]; //BUFFER A = ODD PIXEL
OBJ_PIXEL0 <= i_OBJBUF_DATA[7:0]; //BUFFER B = EVEN PIXEL
end
end
end
///////////////////////////////////////////////////////////
////// PRIORITY HANDLER
////
/*
K005293 priority handler. This chip was reverse-engineered
by Gilles Raimond, Olivier Scherler and me.
Since the exact behavior of the chip was not well known, I made a
brute-force program to test all PR inputs. The tool was programmed with
the advice of Raimond and Scherler, and was executed on my Bubble System.
The source of the program can be found on my GitHub page below:
github.com/ika-musume/BubbleDrive8/tree/master/BubbleDrive8_testprogram
The chip showed us a total of 26 results and suggested that the source
of MAME was a very empirical result.
*/
reg [4:0] priority_mode; //set priority mode
reg [1:0] layer;
wire [2:0] transparency = ~{i_A_TRN_n, i_B_TRN_n, obj_trn_n};
//declare layer type
localparam TMA = 2'b00;
localparam TMB = 2'b01;
localparam OBJ = 2'b10;
//declare cases; all cases are named by Raimond and Scherler
`define PRCASE_A 5'd0 // A
`define PRCASE_A_B 5'd1 // A over B
`define PRCASE_A_B_O 5'd2 // A over B over Object
`define PRCASE_A_BMO 5'd3 // A over (B-masked Object)
`define PRCASE_A_O1 5'd4 // A over Object 1
`define PRCASE_A_O2 5'd5 // A over Object 2
`define PRCASE_A_O_B 5'd6 // A over Object over B
`define PRCASE_B 5'd7 // B
`define PRCASE_B_A 5'd8 // B over A
`define PRCASE_B_A_O 5'd9 // B over A over Object
`define PRCASE_B_O 5'd10 // B over Object
`define PRCASE_B_O_A 5'd11 // B over Object over A
`define PRCASE_O 5'd12 // Object
`define PRCASE_O_A 5'd13 // Object over A
`define PRCASE_O_A_B 5'd14 // Object over A over B
`define PRCASE_O_B 5'd15 // Object over B
`define PRCASE_O_B_A 5'd16 // Object over B over A
`define PRCASE_A_BMO_B 5'd17 // A over (B-masked Object) over B
`define PRCASE_APB_O 5'd18 // (A-punched B) over Object
`define PRCASE_APB_O_A 5'd19 // (A-punched B) over Object over A
`define PRCASE_B_AMO 5'd20 // B over (A-masked Object)
`define PRCASE_B_AMO_A 5'd21 // B over (A-masked Object) over A
`define PRCASE_BPA_O 5'd22 // (B-punched A) over Object
`define PRCASE_BPA_O_B 5'd23 // (B-punched A) over Object over B
`define PRCASE_O_APB 5'd24 // Object over (A-punched B)
`define PRCASE_O_BPA 5'd25 // Object over (B-punched A)
//X-decoder
always @(*)
begin
casez({b_pr, a_pr}) //PR2, PR1, PR4, PR3, PR2, PR1
//|--TMB--| |------TMA-------|
6'b??_0101: priority_mode = `PRCASE_A; // A
6'b?1_1101: priority_mode = `PRCASE_A_B; // A over B
6'b?1_1111: priority_mode = `PRCASE_A_B_O; // A over B over Object
6'b00_1101: priority_mode = `PRCASE_A_BMO; // A over (B-masked Object)
6'b??_0111: priority_mode = `PRCASE_A_O1; // A over Object 1
6'b00_1111: priority_mode = `PRCASE_A_O2; // A over Object 2
6'b10_1111: priority_mode = `PRCASE_A_O_B; // A over Object over B
6'b01_00??: priority_mode = `PRCASE_B; // B
6'b01_10?1: priority_mode = `PRCASE_B_A; // B over A
6'b11_10?1: priority_mode = `PRCASE_B_A_O; // B over A over Object
6'b11_00??: priority_mode = `PRCASE_B_O; // B over Object
6'b11_1000: priority_mode = `PRCASE_B_O; // |
6'b11_1010: priority_mode = `PRCASE_B_O_A; // B over Object over A
6'b00_00??: priority_mode = `PRCASE_O; // Object
6'b00_1?00: priority_mode = `PRCASE_O; // |
6'b??_0100: priority_mode = `PRCASE_O; // |
6'b??_0110: priority_mode = `PRCASE_O_A; // Object over A
6'b00_1110: priority_mode = `PRCASE_O_A; // |
6'b10_1110: priority_mode = `PRCASE_O_A_B; // Object over A over B
6'b10_00??: priority_mode = `PRCASE_O_B; // Object over B
6'b10_1000: priority_mode = `PRCASE_O_B; // |
6'b10_1010: priority_mode = `PRCASE_O_B_A; // Object over B over A
6'b10_1101: priority_mode = `PRCASE_A_BMO_B; // A over (B-masked Object) over B
6'b?1_1100: priority_mode = `PRCASE_APB_O; // (A-punched B) over Object
6'b?1_1110: priority_mode = `PRCASE_APB_O_A; // (A-punched B) over Object over A
6'b01_1000: priority_mode = `PRCASE_B_AMO; // B over (A-masked Object)
6'b01_1010: priority_mode = `PRCASE_B_AMO_A; // B over (A-masked Object) over A
6'b00_10?1: priority_mode = `PRCASE_BPA_O; // (B-punched A) over Object
6'b10_10?1: priority_mode = `PRCASE_BPA_O_B; // (B-punched A) over Object over B
6'b10_1100: priority_mode = `PRCASE_O_APB; // Object over (A-punched B)
6'b00_1010: priority_mode = `PRCASE_O_BPA; // Object over (B-punched A)
default: priority_mode = `PRCASE_A;
endcase
end
//Y and Z-decoder
always @(*)
begin
case(priority_mode)
`PRCASE_A: begin
case(transparency)
3'b110: layer <= TMA; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= TMA; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMA;
endcase
end
`PRCASE_A_B: begin
case(transparency)
3'b110: layer <= TMA; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= TMB; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_A_B_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= TMB; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_A_BMO: begin
case(transparency)
3'b110: layer <= TMA; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= OBJ; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= OBJ;
endcase
end
`PRCASE_A_O1: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= OBJ; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMA;
endcase
end
`PRCASE_A_O2: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= OBJ; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= OBJ;
endcase
end
`PRCASE_A_O_B: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= OBJ; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B: begin
case(transparency)
3'b110: layer <= TMB; 3'b010: layer <= TMB; 3'b011: layer <= TMB; 3'b111: layer <= TMB;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_A: begin
case(transparency)
3'b110: layer <= TMB; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMB;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_A_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= OBJ;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_O_A: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= OBJ; 3'b101: layer <= OBJ;
endcase
end
`PRCASE_O_A: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= TMA; 3'b101: layer <= OBJ;
endcase
end
`PRCASE_O_A_B: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_O_B: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_O_B_A: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_A_BMO_B: begin
case(transparency)
3'b110: layer <= TMA; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= OBJ; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_APB_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= OBJ;
3'b100: layer <= TMB; 3'b000: layer <= OBJ; 3'b001: layer <= OBJ; 3'b101: layer <= TMB;
endcase
end
`PRCASE_APB_O_A: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= TMB; 3'b000: layer <= OBJ; 3'b001: layer <= TMA; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_AMO: begin
case(transparency)
3'b110: layer <= TMB; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= TMB;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_B_AMO_A: begin
case(transparency)
3'b110: layer <= TMB; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= TMB;
3'b100: layer <= TMB; 3'b000: layer <= TMB; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_BPA_O: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= OBJ; 3'b101: layer <= OBJ;
endcase
end
`PRCASE_BPA_O_B: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= TMB; 3'b101: layer <= TMB;
endcase
end
`PRCASE_O_APB: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= OBJ; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= OBJ; 3'b101: layer <= TMB;
endcase
end
`PRCASE_O_BPA: begin
case(transparency)
3'b110: layer <= OBJ; 3'b010: layer <= OBJ; 3'b011: layer <= TMA; 3'b111: layer <= OBJ;
3'b100: layer <= OBJ; 3'b000: layer <= OBJ; 3'b001: layer <= OBJ; 3'b101: layer <= OBJ;
endcase
end
default: begin
case(transparency)
3'b110: layer <= TMA; 3'b010: layer <= TMA; 3'b011: layer <= TMA; 3'b111: layer <= TMA;
3'b100: layer <= TMA; 3'b000: layer <= TMA; 3'b001: layer <= TMA; 3'b101: layer <= TMA;
endcase
end
endcase
end
//output latch
always @(posedge i_EMU_MCLK)
begin
if(!i_EMU_CLK6MPCEN_n)
begin
if(layer == TMA)
begin
o_CD <= {a_palette, i_A_PIXEL};
end
else if(layer == TMB)
begin
o_CD <= {b_palette, i_B_PIXEL};
end
else
begin
o_CD <= {3'b000, obj_pixel};
end
end
end
endmodule

View File

@@ -0,0 +1,70 @@
/*
4416 DRAM
*/
module DRAM16k4
(
input wire i_MCLK,
input wire [7:0] i_ADDR,
input wire [3:0] i_DIN,
output reg [3:0] o_DOUT,
input wire i_RAS_n,
input wire i_CAS_n,
input wire i_WR_n,
input wire i_RD_n
);
reg [3:0] RAM16k4 [16383:0];
reg [7:0] __ROW_ADDR;
reg [5:0] __COL_ADDR;
wire [13:0] __ADDR = {__COL_ADDR, __ROW_ADDR};
/*
MCLK 1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M _|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
PIXEL ----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|
/DTACK ¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|-----------| = access time = 162.75ns
>row
>column
>launch
>CPU acquisition
CHAMPX1 ¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/RAS ___________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|________________
/CAS _______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|____________
*/
always @(posedge i_MCLK)
begin
if(i_RAS_n == 1'b0 && i_CAS_n == 1'b1)
begin
__ROW_ADDR <= i_ADDR;
end
if(i_CAS_n == 1'b0)
begin
__COL_ADDR <= i_ADDR[6:1];
end
end
always @(posedge i_MCLK)
begin
if(i_WR_n == 1'b0)
begin
RAM16k4[__ADDR] <= i_DIN;
end
end
always @(posedge i_MCLK) //read
begin
if(i_RD_n == 1'b0)
begin
o_DOUT <= RAM16k4[__ADDR];
end
end
endmodule

View File

@@ -0,0 +1,22 @@
/*
74373 synchronous latch without tri-state
*/
module LOGIC373
(
input wire i_MCLK,
input wire [7:0] i_D,
output wire [7:0] o_Q,
input wire i_LE
);
reg [7:0] REGISTER;
always @(posedge i_MCLK)
begin
if(i_LE)
begin
REGISTER <= i_DIN;
end
end
assign o_Q = (i_LE) ? i_D : REGISTER;

View File

@@ -1,33 +1,33 @@
/*
6116 2k*8 SRAM ELEMENT
*/
module RAM2k8
(
input wire i_EMU_MCLK,
input wire [10:0] i_ADDR,
input wire [7:0] i_DIN,
output reg [7:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n
);
reg [7:0] RAM2k8 [2047:0];
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n == 1'b0)
begin
RAM2k8[i_ADDR] <= i_DIN;
end
end
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n == 1'b0)
begin
o_DOUT <= RAM2k8[i_ADDR];
end
end
/*
6116 SRAM
*/
module SRAM2k8
(
input wire i_MCLK,
input wire [10:0] i_ADDR,
input wire [7:0] i_DIN,
output reg [7:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n
);
reg [7:0] RAM2k8 [2047:0];
always @(posedge i_MCLK)
begin
if(i_WR_n == 1'b0)
begin
RAM2k8[i_ADDR] <= i_DIN;
end
end
always @(posedge i_MCLK) //read
begin
if(i_RD_n == 1'b0)
begin
o_DOUT <= RAM2k8[i_ADDR];
end
end
endmodule

View File

@@ -1,34 +1,33 @@
/*
6264 4k*8 SRAM ELEMENT
*/
module RAM4k8
(
input wire i_EMU_MCLK,
input wire [11:0] i_ADDR,
input wire [7:0] i_DIN,
output reg [7:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n
);
reg [7:0] RAM4k8 [4095:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n == 1'b0)
begin
o_DOUT <= RAM4k8[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n == 1'b0)
begin
RAM4k8[i_ADDR] <= i_DIN;
end
end
/*
TC5533P SRAM
*/
module SRAM4k8
(
input wire i_MCLK,
input wire [10:0] i_ADDR,
input wire [7:0] i_DIN,
output reg [7:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n
);
reg [7:0] RAM4k8 [4095:0];
always @(posedge i_MCLK)
begin
if(i_WR_n == 1'b0)
begin
RAM4k8[i_ADDR] <= i_DIN;
end
end
always @(posedge i_MCLK) //read
begin
if(i_RD_n == 1'b0)
begin
o_DOUT <= RAM4k8[i_ADDR];
end
end
endmodule

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE pinplan>
<pinplan intended_family="Cyclone IV E" variation_name="pll" megafunction_name="ALTPLL" specifies="all_ports">
<global>
<pin name="areset" direction="input" scope="external" />
<pin name="inclk0" direction="input" scope="external" source="clock" />
<pin name="c0" direction="output" scope="external" source="clock" />
<pin name="locked" direction="output" scope="external" />
</global>
</pinplan>

View File

@@ -0,0 +1,6 @@
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
set_global_assignment -name IP_TOOL_VERSION "17.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_bb.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]

View File

@@ -0,0 +1,320 @@
// megafunction wizard: %ALTPLL%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altpll
// ============================================================
// File Name: pll.v
// Megafunction Name(s):
// altpll
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 17.1.0 Build 590 10/25/2017 SJ Lite Edition
// ************************************************************
//Copyright (C) 2017 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Intel Program License
//Subscription Agreement, the Intel Quartus Prime License Agreement,
//the Intel FPGA IP License Agreement, or other applicable license
//agreement, including, without limitation, that your use is for
//the sole purpose of programming logic devices manufactured by
//Intel and sold by Intel or its authorized distributors. Please
//refer to the applicable agreement for further details.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pll (
areset,
inclk0,
c0,
locked);
input areset;
input inclk0;
output c0;
output locked;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 areset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [0:0] sub_wire2 = 1'h0;
wire [4:0] sub_wire3;
wire sub_wire5;
wire sub_wire0 = inclk0;
wire [1:0] sub_wire1 = {sub_wire2, sub_wire0};
wire [0:0] sub_wire4 = sub_wire3[0:0];
wire c0 = sub_wire4;
wire locked = sub_wire5;
altpll altpll_component (
.areset (areset),
.inclk (sub_wire1),
.clk (sub_wire3),
.locked (sub_wire5),
.activeclock (),
.clkbad (),
.clkena ({6{1'b1}}),
.clkloss (),
.clkswitch (1'b0),
.configupdate (1'b0),
.enable0 (),
.enable1 (),
.extclk (),
.extclkena ({4{1'b1}}),
.fbin (1'b1),
.fbmimicbidir (),
.fbout (),
.fref (),
.icdrclk (),
.pfdena (1'b1),
.phasecounterselect ({4{1'b1}}),
.phasedone (),
.phasestep (1'b1),
.phaseupdown (1'b1),
.pllena (1'b1),
.scanaclr (1'b0),
.scanclk (1'b0),
.scanclkena (1'b1),
.scandata (1'b0),
.scandataout (),
.scandone (),
.scanread (1'b0),
.scanwrite (1'b0),
.sclkout0 (),
.sclkout1 (),
.vcooverrange (),
.vcounderrange ());
defparam
altpll_component.bandwidth_type = "AUTO",
altpll_component.clk0_divide_by = 3125,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 1152,
altpll_component.clk0_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 20000,
altpll_component.intended_device_family = "Cyclone IV E",
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
altpll_component.lpm_type = "altpll",
altpll_component.operation_mode = "NORMAL",
altpll_component.pll_type = "AUTO",
altpll_component.port_activeclock = "PORT_UNUSED",
altpll_component.port_areset = "PORT_USED",
altpll_component.port_clkbad0 = "PORT_UNUSED",
altpll_component.port_clkbad1 = "PORT_UNUSED",
altpll_component.port_clkloss = "PORT_UNUSED",
altpll_component.port_clkswitch = "PORT_UNUSED",
altpll_component.port_configupdate = "PORT_UNUSED",
altpll_component.port_fbin = "PORT_UNUSED",
altpll_component.port_inclk0 = "PORT_USED",
altpll_component.port_inclk1 = "PORT_UNUSED",
altpll_component.port_locked = "PORT_USED",
altpll_component.port_pfdena = "PORT_UNUSED",
altpll_component.port_phasecounterselect = "PORT_UNUSED",
altpll_component.port_phasedone = "PORT_UNUSED",
altpll_component.port_phasestep = "PORT_UNUSED",
altpll_component.port_phaseupdown = "PORT_UNUSED",
altpll_component.port_pllena = "PORT_UNUSED",
altpll_component.port_scanaclr = "PORT_UNUSED",
altpll_component.port_scanclk = "PORT_UNUSED",
altpll_component.port_scanclkena = "PORT_UNUSED",
altpll_component.port_scandata = "PORT_UNUSED",
altpll_component.port_scandataout = "PORT_UNUSED",
altpll_component.port_scandone = "PORT_UNUSED",
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
altpll_component.port_clk1 = "PORT_UNUSED",
altpll_component.port_clk2 = "PORT_UNUSED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
altpll_component.port_clk5 = "PORT_UNUSED",
altpll_component.port_clkena0 = "PORT_UNUSED",
altpll_component.port_clkena1 = "PORT_UNUSED",
altpll_component.port_clkena2 = "PORT_UNUSED",
altpll_component.port_clkena3 = "PORT_UNUSED",
altpll_component.port_clkena4 = "PORT_UNUSED",
altpll_component.port_clkena5 = "PORT_UNUSED",
altpll_component.port_extclk0 = "PORT_UNUSED",
altpll_component.port_extclk1 = "PORT_UNUSED",
altpll_component.port_extclk2 = "PORT_UNUSED",
altpll_component.port_extclk3 = "PORT_UNUSED",
altpll_component.self_reset_on_loss_lock = "OFF",
altpll_component.width_clock = 5;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "18.431999"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "18.43200000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3125"
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1152"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf
// Retrieval info: CBX_MODULE_PREFIX: ON

View File

@@ -0,0 +1,210 @@
// megafunction wizard: %ALTPLL%VBB%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altpll
// ============================================================
// File Name: pll.v
// Megafunction Name(s):
// altpll
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 17.1.0 Build 590 10/25/2017 SJ Lite Edition
// ************************************************************
//Copyright (C) 2017 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Intel Program License
//Subscription Agreement, the Intel Quartus Prime License Agreement,
//the Intel FPGA IP License Agreement, or other applicable license
//agreement, including, without limitation, that your use is for
//the sole purpose of programming logic devices manufactured by
//Intel and sold by Intel or its authorized distributors. Please
//refer to the applicable agreement for further details.
module pll (
areset,
inclk0,
c0,
locked);
input areset;
input inclk0;
output c0;
output locked;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 areset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "18.431999"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "18.43200000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3125"
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1152"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf
// Retrieval info: CBX_MODULE_PREFIX: ON

View File

@@ -1,343 +0,0 @@
module VideoTimingGenerator
(
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
output wire o_EMU_9MPOSCEN_n,
output wire o_EMU_9MNEGCEN_n,
output wire o_EMU_6MPOSCEN_n,
output wire o_EMU_6MNEGCEN_n,
input wire i_MRST_n,
input wire i_HFLIP,
input wire i_VFLIP,
output wire o_HBLANK_n,
output reg o_VBLANK_n = 1'b1,
output reg o_VBLANKH_n = 1'b1,
output wire [8:0] o_HABSCNTR, //256H 128H 64H 32H 16H 8H 4H 2H 1H
output wire [7:0] o_VABSCNTR, // 128V 64V 32V 16V 8V 4V 2V 1V
output wire [7:0] o_HFLIPCNTR, // 128H* 64H* 32H* 16H* 8H* 4H* 2H* 1H*
output wire [7:0] o_VFLIPCNTR, // 128V* 64V* 32V* 16V* 8V* 4V* 2V* 1V*
output reg o_VCLK = 1'b0,
output wire o_VSYNC_n,
output wire o_CSYNC_n,
output reg o_FRAMEPARITY = 1'b0,
output reg o_DMA_n = 1'b1,
output wire o_BLANK_n,
output wire o_OBJBUFCLR, //1=clear buffer(write 0x00) data after reading, during an active video period(OBJ CLR on Nemesis schematic)
output wire o_OBJBUFMUX, //1=blanking, 0=active video period(OBJ R/W on Nemesis schematic)
//test
output reg o_OBJBUFRDCEN_n = 1'b1,
output reg o_OBJBUFWRCEN_n = 1'b1,
//reference ??
output reg o_CLK9M_ref = 1'b1,
output reg o_CLK6M_ref = 1'b1,
output wire o_TIME1_ref,
output wire o_TIME2_ref,
output wire o_CHRMUX_ref,
output wire o_VRTIME_ref,
output wire o_OBJBUFWE_n_ref, //14H LS157 pin14, clears buffer during WE is down when an active video period(BLK on Nemesis schematic)
output wire o_OBJBUFRAS_n_ref, //should be delayed by a 470pF cap, about 50ns
//emulator signal
output wire [3:0] o_MCLKCNTR12_emu
);
///////////////////////////////////////////////////////////
////// CLOCK ENABLE SIGNAL GENERATOR
////
/*
1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
*/
reg [3:0] ref_clock_counter_12 = 4'd11;
assign o_MCLKCNTR12_emu = ref_clock_counter_12;
always @(posedge i_EMU_MCLK)
begin
if(ref_clock_counter_12 < 4'd11)
begin
ref_clock_counter_12 <= ref_clock_counter_12 + 4'd1;
end
else
begin
ref_clock_counter_12 <= 4'd0;
end
end
reg [3:0] cen_register = 4'b1111;
assign {o_EMU_9MPOSCEN_n, o_EMU_9MNEGCEN_n, o_EMU_6MPOSCEN_n, o_EMU_6MNEGCEN_n} = cen_register;
always @(negedge i_EMU_MCLK)
begin
case(ref_clock_counter_12)
4'd0: cen_register <= 4'b1111;
4'd1: cen_register <= 4'b1011;
4'd2: cen_register <= 4'b1111;
4'd3: cen_register <= 4'b0110;
4'd4: cen_register <= 4'b1111;
4'd5: cen_register <= 4'b1001;
4'd6: cen_register <= 4'b1111;
4'd7: cen_register <= 4'b0111;
4'd8: cen_register <= 4'b1111;
4'd9: cen_register <= 4'b1010;
4'd10: cen_register <= 4'b1111;
4'd11: cen_register <= 4'b0101;
default: cen_register <= 4'b1111;
endcase
end
///////////////////////////////////////////////////////////
////// PIXEL COUNTER/BLANKING/SYNC/DMA
////
reg [8:0] horizontal_counter = 9'd511;
assign o_HABSCNTR = horizontal_counter;
assign o_HFLIPCNTR = horizontal_counter[7:0] ^ {8{i_HFLIP}};
assign o_HBLANK_n = horizontal_counter[8];
reg [8:0] vertical_counter = 9'd511;
assign o_VABSCNTR = vertical_counter[7:0];
assign o_VFLIPCNTR = vertical_counter[7:0] ^ {8{i_VFLIP}};
assign o_VSYNC_n = vertical_counter[8];
always @(posedge i_EMU_MCLK)
begin
if(i_MRST_n == 1'b0) //synchronous reset
begin
horizontal_counter <= 9'd511;
end
else
begin //count up
if(o_EMU_6MPOSCEN_n == 1'b0)
begin
if(horizontal_counter < 9'd511) //h count up
begin
if(horizontal_counter == 9'd175) //v count up
begin
if(vertical_counter < 9'd511)
begin
//VBLANK
if(vertical_counter > 9'd495 || vertical_counter < 9'd271)
begin
o_VBLANK_n <= 1'b0;
end
else
begin
o_VBLANK_n <= 1'b1;
end
//VBLANK**
if(vertical_counter > 9'd247 && vertical_counter < 9'd271)
begin
o_VBLANKH_n <= 1'b0;
end
else
begin
o_VBLANKH_n <= 1'b1;
end
//256V
if(vertical_counter == 9'd495) //flip parity value
begin
o_FRAMEPARITY <= ~o_FRAMEPARITY;
end
//DMA
if(vertical_counter > 9'd478 && vertical_counter < 9'd496)
begin
o_DMA_n <= 1'b0;
end
else
begin
o_DMA_n <= 1'b1;
end
vertical_counter <= vertical_counter + 9'd1;
end
else
begin
vertical_counter <= 9'd248;
end
end
if(horizontal_counter > 9'd174 && horizontal_counter < 9'd207)
begin
o_VCLK <= 1'b1;
end
else
begin
o_VCLK <= 1'b0;
end
horizontal_counter <= horizontal_counter + 9'd1;
end
else //h loop
begin
horizontal_counter <= 9'd128;
end
end
end
end
///////////////////////////////////////////////////////////
////// SYNC GENERATOR
////
assign o_VSYNC_n = vertical_counter[8];
assign o_CSYNC_n = o_VSYNC_n & ~o_VCLK;
///////////////////////////////////////////////////////////
////// BLANK SCREEN/OBJBUF CLR/MUX SIGNAL GENERATOR
////
/*
This block generates:
o_BLANK_n (BLK)
o_OBJBUFCLR (OBJ CLR)
o_OBJBUFMUX (OBJ R/W)
*/
reg [21:0] delay_shift_register = {22{1'b1}};
assign o_BLANK_n = delay_shift_register[21];
assign o_OBJBUFCLR = delay_shift_register[17];
assign o_OBJBUFMUX = ~delay_shift_register[17];
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_6MPOSCEN_n == 1'b0)
begin
delay_shift_register[0] <= o_HBLANK_n & o_VBLANK_n;
delay_shift_register[21:1] <= delay_shift_register[20:0];
end
end
///////////////////////////////////////////////////////////
////// RAM CONTROL SIGNAL GENERATOR
////
/*
This block generates:
o_TIME1 (TIME1) SCROLL/SPRITE RAM read latch enable(active high: LS373)
o_TIME2 (TIME2) SCROLL/SPRITE RAM write enable(active low: 6116 WE)
o_CHRMUX (CHAMPX)
o_VRTIME (VRTIME) VRAM1/2 chip enable(active high: 6264 CE)
o_OBJBUFWE_n (dram WE) SPRITE FRAME BUFFER write enable(active low: 4164 WE)
o_OBJBUFRAS_n (dram RAS) SPRITE FRAME BUFFER row address strobe(active low: 4164 RAS)
1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
---(511)---|----(0)----|----(1)----|----(2)----|
TIME1 ___________________|¯¯¯|___________________|¯¯¯|
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|
CHRMUX ¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯
VRTIME ¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯
BUFWE ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
BUFRAS ___________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|____
dl-ras ____________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|___
for block ram
BUFWR ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
BUFRD ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|
*/
reg [5:0] ram_control_register = 6'b011011;
assign o_TIME1 = ram_control_register[5];
assign o_TIME2 = ram_control_register[4];
assign o_CHRMUX = ram_control_register[3];
assign o_VRTIME = ram_control_register[2];
assign o_OBJBUFWE_n = ram_control_register[1];
assign o_OBJBUFRAS_n = ram_control_register[0];
always @(posedge i_EMU_MCLK)
begin
case(o_MCLKCNTR12_emu[3:0])
4'd0: ram_control_register <= 6'b010011; //cycle 1
4'd1: ram_control_register <= 6'b010111; //cycle 2
4'd2: ram_control_register <= 6'b010111; //cycle 3
4'd3: ram_control_register <= 6'b101110; //cycle 4
4'd4: ram_control_register <= 6'b101110; //cycle 5
4'd5: ram_control_register <= 6'b011110; //cycle 6
4'd6: ram_control_register <= 6'b011110; //cycle 7
4'd7: ram_control_register <= 6'b011110; //cycle 8
4'd8: ram_control_register <= 6'b011110; //cycle 9
4'd9: ram_control_register <= 6'b011100; //cycle 10
4'd10: ram_control_register <= 6'b011100; //cycle 11
4'd11: ram_control_register <= 6'b010011; //cycle 0
default: ram_control_register <= 6'b011011;
endcase
end
///////////////////////////////////////////////////////////
////// REFERENCE CLOCK GENERATOR
////
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_6MPOSCEN_n == 1'b0)
begin
o_CLK6M_ref <= 1'b1;
end
else if(o_EMU_6MNEGCEN_n == 1'b0)
begin
o_CLK6M_ref <= 1'b0;
end
else
begin
o_CLK6M_ref <= o_CLK6M_ref;
end
end
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_9MPOSCEN_n == 1'b0)
begin
o_CLK9M_ref <= 1'b1;
end
else if(o_EMU_9MNEGCEN_n == 1'b0)
begin
o_CLK9M_ref <= 1'b0;
end
else
begin
o_CLK9M_ref <= o_CLK9M_ref;
end
end
endmodule

View File

@@ -1,112 +0,0 @@
`timescale 10ps/10ps
module VideoTimingGenerator_tb;
//reset & clock
reg MCLK = 1'b1;
reg MRST_n = 1'b0;
wire POSCEN9M_n;
wire NEGCEN9M_n;
wire POSCEN6M_n;
wire NEGCEN6M_n;
wire HBLANK_n;
wire VBLANK_n;
wire VBLANKH_n;
wire [8:0] HABSCNTR;
wire [7:0] VABSCNTR;
wire [7:0] HFLIPCNTR;
wire [7:0] VFLIPCNTR;
wire VCLK;
wire VSYNC_n;
wire CSYNC_;
wire FRAMEPARITY;
wire DMA_n;
wire BLANK_n;
wire TIME1;
wire TIME2;
wire CHRMUX;
wire VRTIME;
wire OBJBUFWE_n;
wire OBJBUFRAS_n;
wire OBJBUFCLR;
wire OBJBUFMUX;
wire OBJBUFRDCEN_n;
wire OBJBUFWRCEN_n;
wire CLK9M_ref;
wire CLK6M_ref;
wire CPUDATA;
wire [4:0] MCLKCNTR12_emu;
VideoTimingGenerator VTG0
(
.i_MCLK (MCLK ),
.i_MRST_n (MRST_n ),
.i_HFLIP (1'b0 ),
.i_VFLIP (1'b0 ),
.o_9MPOSCEN_n (POSCEN9M_n ),
.o_9MNEGCEN_n (NEGCEN9M_n ),
.o_6MPOSCEN_n (POSCEN6M_n ),
.o_6MNEGCEN_n (NEGCEN6M_n ),
.o_HBLANK_n (HBLANK_n ),
.o_VBLANK_n (VBLANK_n ),
.o_VBLANKH_n (VBLANKH_n ),
.o_HABSCNTR (HABSCNTR ),
.o_VABSCNTR (VABSCNTR ),
.o_HFLIPCNTR (HFLIPCNTR ),
.o_VFLIPCNTR (VFLIPCNTR ),
.o_VCLK (VCLK ),
.o_VSYNC_n (VSYNC_n ),
.o_CSYNC_n (CSYNC_n ),
.o_FRAMEPARITY (FRAMEPARITY ),
.o_DMA_n (DMA_n ),
.o_BLANK_n (BLANK_n ),
.o_TIME1_ref (TIME1 ),
.o_TIME2_ref (TIME2 ),
.o_CHRMUX_ref (CHRMUX ),
.o_VRTIME_ref (VRTIME ),
.o_OBJBUFWE_n_ref (OBJBUFWE_n ),
.o_OBJBUFRAS_n_ref (OBJBUFRAS_n ),
.o_OBJBUFCLR (OBJBUFCLR ),
.o_OBJBUFMUX (OBJBUFMUX ),
.o_OBJBUFRDCEN_n (OBJBUFRDCEN_n ),
.o_OBJBUFWRCEN_n (OBJBUFWRCEN_n ),
.o_CLK9M_ref (CLK9M_ref ),
.o_CLK6M_ref (CLK6M_ref ),
.o_MCLKCNTR12_emu (MCLKCNTR12_emu )
);
K005291 TG0
(
.i_MCLK (MCLK ),
.i_HFLIP (1'b0 ),
.i_VFLIP (1'b0 ),
.i_6MPOSCEN_n (POSCEN6M_n ),
.i_6MNEGCEN_n (NEGCEN6M_n ),
.i_HABSCNTR (HABSCNTR ),
.i_VABSCNTR (VABSCNTR ),
.i_HFLIPCNTR (HFLIPCNTR ),
.i_VFLIPCNTR (VFLIPCNTR ),
.i_VCLK (VCLK ),
.i_CPUADDR (12'b111111111111 ),
.io_CPUDATA (CPUDATA ),
.i_CPURW (1'b1 ),
.i_CPUUDS_n (1'b1 ),
.i_CPULDS_n (1'b1 ),
.i_VZCS_n (1'b1 ),
.i_VCS1_n (1'b1 ),
.i_VCS2_n (1'b1 ),
.i_MCLKCNTR12_emu (MCLKCNTR12_emu )
);
always #1 MCLK = ~MCLK;
initial
begin
#7 MRST_n = 1'b1;
end
endmodule

View File

@@ -1,229 +0,0 @@
module K005291
(
//emulator
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
input wire i_EMU_6MPOSCEN_n,
input wire i_EMU_6MNEGCEN_n,
input wire [4:0] i_EMU_TIMING, //asynchronous RAM timings
//CPU flip
input wire i_HFLIP,
input wire i_VFLIP,
//HV counters
input wire [8:0] i_HABSCNTR, //256H 128H 64H 32H 16H 8H 4H 2H 1H
input wire [7:0] i_VABSCNTR, // 128V 64V 32V 16V 8V 4V 2V 1V
input wire [7:0] i_HFLIPCNTR, // 128H* 64H* 32H* 16H* 8H* 4H* 2H* 1H*
input wire [7:0] i_VFLIPCNTR, // 128V* 64V* 32V* 16V* 8V* 4V* 2V* 1V*
input wire i_VCLK,
//CPU address/data buses
input wire [11:0] i_CPUADDR,
inout wire [15:0] io_CPUDATA,
input wire i_CPURW,
input wire i_CPULDS_n,
input wire i_CPUUDS_n,
input wire i_VZCS_n,
input wire i_VCS1_n,
input wire i_VCS2_n,
//to CHARRAM
output wire [13:0] o_TILEADDR,
//to K005293
output wire [3:0] o_PRIORITY,
output wire [6:0] o_PALETTE,
output wire o_HFLIPBIT,
output wire o_SHIFTA1,
output wire o_SHIFTA2,
output wire o_SHIFTB
);
///////////////////////////////////////////////////////////
////// PIXEL COUNTER BITS
////
wire ABS_n256H = ~i_HABSCNTR[8];
wire ABS_128HA = (i_HABSCNTR[8] & i_HABSCNTR[7]) | (~i_HABSCNTR[8] & i_HABSCNTR[5]);
wire ABS_64H = i_HABSCNTR[6];
wire ABS_32H = i_HABSCNTR[5];
wire ABS_16H = i_HABSCNTR[4];
wire ABS_8H = i_HABSCNTR[3];
wire ABS_4H = i_HABSCNTR[2];
wire ABS_2H = i_HABSCNTR[1];
wire ABS_1H = i_HABSCNTR[0];
wire FLIP_n256H = ABS_n256H ^ i_HFLIP;
wire FLIP_256H = ~i_HABSCNTR[8] ^ i_HFLIP;
wire FLIP_128H = i_HFLIPCNTR[7];
wire FLIP_128HA = ABS_128HA ^ i_HFLIP;
wire FLIP_64H = i_HFLIPCNTR[6];
wire FLIP_32H = i_HFLIPCNTR[5];
wire FLIP_16H = i_HFLIPCNTR[4];
wire FLIP_8H = i_HFLIPCNTR[3];
wire FLIP_4H = i_HFLIPCNTR[2];
wire FLIP_2H = i_HFLIPCNTR[1];
wire FLIP_1H = i_HFLIPCNTR[0];
wire ABS_128V = i_VABSCNTR[7];
wire ABS_64V = i_VABSCNTR[6];
wire ABS_32V = i_VABSCNTR[5];
wire ABS_16V = i_VABSCNTR[4];
wire ABS_8V = i_VABSCNTR[3];
wire ABS_4V = i_VABSCNTR[2];
wire ABS_2V = i_VABSCNTR[1];
wire ABS_1V = i_VABSCNTR[0];
wire FLIP_128V = i_VFLIPCNTR[7];
wire FLIP_64V = i_VFLIPCNTR[6];
wire FLIP_32V = i_VFLIPCNTR[5];
wire FLIP_16V = i_VFLIPCNTR[4];
wire FLIP_8V = i_VFLIPCNTR[3];
wire FLIP_4V = i_VFLIPCNTR[2];
wire FLIP_2V = i_VFLIPCNTR[1];
wire FLIP_1V = i_VFLIPCNTR[0];
///////////////////////////////////////////////////////////
////// SCROLL RAM
////
wire [10:0] scrollram_address;
assign scrollram_address = (~i_VCLK == 1'b0) ?
{1'b0, ABS_4H, ABS_2H, FLIP_128V, FLIP_64V, FLIP_32V, FLIP_16V, FLIP_8V, FLIP_4V, FLIP_2V, FLIP_1V} : //HORIZONTAL SCROLL
{1'b1, 1'b1, 1'b1, 1'b1, ABS_4H, FLIP_256H, FLIP_128H, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H}; //VERTICAL SCROLL
wire [7:0] scroll_value_data;
SCROLLRAM SCROLLRAM_DEVICE
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_EMU_TIMING (i_EMU_TIMING ),
.i_VZCS_n (i_VZCS_n ),
.i_CPUADDR (i_CPUADDR ),
.io_CPUDATA (io_CPUDATA ),
.i_CPURW (i_CPURW ),
.i_CPULDS_n (i_CPULDS_n ),
.i_GFXADDR (scrollram_address ),
.o_GFXDATA (scroll_value_data )
);
///////////////////////////////////////////////////////////
////// SCROLL DATA LATCHES
////
//HSCROLL
reg [8:0] TMA_HSCROLL_VALUE = 9'h1F;
reg [8:0] TMB_HSCROLL_VALUE = 9'h1F;
always @(posedge i_EMU_MCLK)
begin
if(i_EMU_6MPOSCEN_n == 1'b0)
begin
case({ABS_4H, ABS_2H, ABS_1H})
3'd1: begin TMA_HSCROLL_VALUE[7:0] <= scroll_value_data; end //latch TM-A lower bits at px1
3'd3: begin TMA_HSCROLL_VALUE[8] <= scroll_value_data[0]; end //latch TM-B high bit at px3
3'd5: begin TMB_HSCROLL_VALUE[7:0] <= scroll_value_data; end //latch TM-A lower bits at px5
3'd7: begin TMB_HSCROLL_VALUE[8] <= scroll_value_data[0]; end //latch TM-B high bit at px7
default: begin end
endcase
end
end
//VSCROLL
reg [7:0] TMAB_VSCROLL_VALUE = 8'hF;
always @(posedge i_EMU_MCLK)
begin
if(i_EMU_6MPOSCEN_n == 1'b0)
begin
case({ABS_4H, ABS_2H, ABS_1H})
3'd3: begin TMAB_VSCROLL_VALUE <= scroll_value_data; end //latch TM-B second at px3
3'd7: begin TMAB_VSCROLL_VALUE <= scroll_value_data; end //latch TM-A first at px7
default: begin end
endcase
end
end
///////////////////////////////////////////////////////////
////// SHIFT SIGNAL GENERATOR
////
assign o_SHIFTA1 = (TMA_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd7) ? 1'b0 : 1'b1;
assign o_SHIFTA2 = (TMB_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd3) ? 1'b0 : 1'b1;
assign o_SHIFTB = (TMB_HSCROLL_VALUE[2:0] + {FLIP_4H, FLIP_2H, FLIP_1H} == 3'd3) ? 1'b0 : 1'b1;
///////////////////////////////////////////////////////////
////// VRAM TILE ADDRESS GENERATOR
////
wire [5:0] horizontal_tile_address_bus; //6 bit: 64 horizontal tiles(512 horizontal pixels)
assign horizontal_tile_address_bus = (ABS_4H == 1'b0) ?
TMA_HSCROLL_VALUE[8:3] + {FLIP_n256H, FLIP_128HA, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H} :
TMB_HSCROLL_VALUE[8:3] + {FLIP_n256H, FLIP_128HA, FLIP_64H, FLIP_32H, FLIP_16H, FLIP_8H};
wire [7:0] vertical_tile_address_bus;
assign vertical_tile_address_bus = TMAB_VSCROLL_VALUE + {FLIP_128V, FLIP_64V, FLIP_32V, FLIP_16V, FLIP_8V, FLIP_4V, FLIP_2V, FLIP_1V};
wire [11:0] vram_tile_address_bus;
assign vram_tile_address_bus = {ABS_4H, vertical_tile_address_bus[7:3], horizontal_tile_address_bus};
///////////////////////////////////////////////////////////
////// VRAM1+2
////
wire [15:0] vram1_gfx_data;
wire [7:0] vram2_gfx_data;
assign o_PRIORITY = vram1_gfx_data[15:12];
assign o_HFLIPBIT = vram2_gfx_data[7];
assign o_PALETTE = vram2_gfx_data[6:0];
VRAM VRAM_DEVICE
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_EMU_TIMING (i_EMU_TIMING ),
.i_VCS1_n (i_VCS1_n ),
.i_VCS2_n (i_VCS2_n ),
.i_CPUADDR (i_CPUADDR ),
.io_CPUDATA (io_CPUDATA ),
.i_CPURW (i_CPURW ),
.i_CPUUDS_n (i_CPUUDS_n ),
.i_CPULDS_n (i_CPULDS_n ),
.i_GFXADDR (vram_tile_address_bus ),
.o_VRAM1GFXDATA (vram1_gfx_data ),
.o_VRAM2GFXDATA (vram2_gfx_data )
);
///////////////////////////////////////////////////////////
////// CHARRAM ADDRESS GENERATOR
////
always @(i_EMU_MCLK)
begin
if(i_EMU_6MPOSCEN_n == 1'b0)
begin
if({ABS_2H, ABS_1H} == 2'd3) //at every negedge of 2H(pixel 3)
begin
o_TILEADDR[2:0] <= ({FLIP_4V, FLIP_2V, FLIP_1V} + TMAB_VSCROLL_VALUE[2:0]) ^ {3{vram1_gfx_data[11]}}; //{VA1, 2, 4} ^ vflip register bit = tile line address
o_TILEADDR[13:3] <= vram1_gfx_data[10:0]; //tile address
end
end
end
endmodule

View File

@@ -1,277 +0,0 @@
module K005292
(
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
output wire o_EMU_9MPOSCEN_n,
output wire o_EMU_9MNEGCEN_n,
output wire o_EMU_6MPOSCEN_n,
output wire o_EMU_6MNEGCEN_n,
output wire [4:0] o_EMU_TIMING,
output reg o_REF_CLK9M = 1'b1,
output reg o_REF_CLK6M = 1'b1,
input wire i_MRST_n,
input wire i_HFLIP,
input wire i_VFLIP,
output wire o_HBLANK_n,
output reg o_VBLANK_n = 1'b1,
output reg o_VBLANKH_n = 1'b1,
output wire [8:0] o_HABSCNTR, //256H 128H 64H 32H 16H 8H 4H 2H 1H
output wire [7:0] o_VABSCNTR, // 128V 64V 32V 16V 8V 4V 2V 1V
output wire [7:0] o_HFLIPCNTR, // 128H* 64H* 32H* 16H* 8H* 4H* 2H* 1H*
output wire [7:0] o_VFLIPCNTR, // 128V* 64V* 32V* 16V* 8V* 4V* 2V* 1V*
output reg o_VCLK = 1'b0,
output reg o_FRAMEPARITY = 1'b0,
output reg o_DMA_n = 1'b1,
output wire o_VSYNC_n,
output wire o_CSYNC_n,
output wire o_BLANK_n,
output wire o_OBJBUFCLR, //1=clear buffer(write 0x00) data after reading, during an active video period(OBJ CLR on Nemesis schematic)
output wire o_OBJBUFMUX, //1=blanking, 0=active video period(OBJ R/W on Nemesis schematic)
);
///////////////////////////////////////////////////////////
////// CLOCK ENABLE SIGNAL GENERATOR
////
/*
1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
*/
reg [3:0] ref_clock_counter_12 = 4'd11;
reg [2:0] ref_clock_counter_6 = 4'd5;
always @(posedge i_EMU_MCLK)
begin
if(ref_clock_counter_12 < 4'd11)
begin
ref_clock_counter_12 <= ref_clock_counter_12 + 4'd1;
end
else
begin
ref_clock_counter_12 <= 4'd0;
end
if(ref_clock_counter_6 < 3'd5)
begin
ref_clock_counter_6 <= ref_clock_counter_6 + 3'd1;
end
else
begin
ref_clock_counter_6 <= 3'd0;
end
end
reg [3:0] cen_register = 4'b1111;
assign {o_EMU_9MPOSCEN_n, o_EMU_9MNEGCEN_n, o_EMU_6MPOSCEN_n, o_EMU_6MNEGCEN_n} = cen_register;
always @(negedge i_EMU_MCLK)
begin
case(ref_clock_counter_12)
4'd0: cen_register <= 4'b1111;
4'd1: cen_register <= 4'b1011;
4'd2: cen_register <= 4'b1111;
4'd3: cen_register <= 4'b0110;
4'd4: cen_register <= 4'b1111;
4'd5: cen_register <= 4'b1001;
4'd6: cen_register <= 4'b1111;
4'd7: cen_register <= 4'b0111;
4'd8: cen_register <= 4'b1111;
4'd9: cen_register <= 4'b1010;
4'd10: cen_register <= 4'b1111;
4'd11: cen_register <= 4'b0101;
default: cen_register <= 4'b1111;
endcase
end
///////////////////////////////////////////////////////////
////// REFERENCE CLOCK GENERATOR
////
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_6MPOSCEN_n == 1'b0)
begin
o_CLK6M_ref <= 1'b1;
end
else if(o_EMU_6MNEGCEN_n == 1'b0)
begin
o_CLK6M_ref <= 1'b0;
end
else
begin
o_CLK6M_ref <= o_CLK6M_ref;
end
end
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_9MPOSCEN_n == 1'b0)
begin
o_CLK9M_ref <= 1'b1;
end
else if(o_EMU_9MNEGCEN_n == 1'b0)
begin
o_CLK9M_ref <= 1'b0;
end
else
begin
o_CLK9M_ref <= o_CLK9M_ref;
end
end
///////////////////////////////////////////////////////////
////// PIXEL COUNTER/BLANKING/SYNC/DMA
////
reg [8:0] horizontal_counter = 9'd511;
assign o_HABSCNTR = horizontal_counter;
assign o_HFLIPCNTR = horizontal_counter[7:0] ^ {8{i_HFLIP}};
assign o_HBLANK_n = horizontal_counter[8];
reg [8:0] vertical_counter = 9'd511;
assign o_VABSCNTR = vertical_counter[7:0];
assign o_VFLIPCNTR = vertical_counter[7:0] ^ {8{i_VFLIP}};
assign o_VSYNC_n = vertical_counter[8];
always @(posedge i_EMU_MCLK)
begin
if(i_MRST_n == 1'b0) //synchronous reset
begin
horizontal_counter <= 9'd511;
end
else
begin //count up
if(o_6MPOSCEN_n == 1'b0)
begin
if(horizontal_counter < 9'd511) //h count up
begin
if(horizontal_counter == 9'd175) //v count up
begin
if(vertical_counter < 9'd511)
begin
//VBLANK
if(vertical_counter > 9'd495 || vertical_counter < 9'd271)
begin
o_VBLANK_n <= 1'b0;
end
else
begin
o_VBLANK_n <= 1'b1;
end
//VBLANK**
if(vertical_counter > 9'd247 && vertical_counter < 9'd271)
begin
o_VBLANKH_n <= 1'b0;
end
else
begin
o_VBLANKH_n <= 1'b1;
end
//256V
if(vertical_counter == 9'd495) //flip parity value
begin
o_FRAMEPARITY <= ~o_FRAMEPARITY;
end
//DMA
if(vertical_counter > 9'd478 && vertical_counter < 9'd496)
begin
o_DMA_n <= 1'b0;
end
else
begin
o_DMA_n <= 1'b1;
end
vertical_counter <= vertical_counter + 9'd1;
end
else
begin
vertical_counter <= 9'd248;
end
end
if(horizontal_counter > 9'd174 && horizontal_counter < 9'd207)
begin
o_VCLK <= 1'b1;
end
else
begin
o_VCLK <= 1'b0;
end
horizontal_counter <= horizontal_counter + 9'd1;
end
else //h loop
begin
horizontal_counter <= 9'd128;
end
end
end
end
///////////////////////////////////////////////////////////
////// SYNC GENERATOR
////
assign o_VSYNC_n = vertical_counter[8];
assign o_CSYNC_n = o_VSYNC_n & ~o_VCLK;
///////////////////////////////////////////////////////////
////// BLANK SCREEN/OBJBUF CLR/MUX SIGNAL GENERATOR
////
/*
This block generates:
o_BLANK_n (BLK)
o_OBJBUFCLR (OBJ CLR)
o_OBJBUFMUX (OBJ R/W)
*/
reg [21:0] delay_shift_register = {22{1'b1}};
assign o_BLANK_n = delay_shift_register[21];
assign o_OBJBUFCLR = delay_shift_register[17];
assign o_OBJBUFMUX = ~delay_shift_register[17];
always @(posedge i_EMU_MCLK)
begin
if(o_EMU_6MPOSCEN_n == 1'b0)
begin
delay_shift_register[0] <= o_HBLANK_n & o_VBLANK_n;
delay_shift_register[21:1] <= delay_shift_register[20:0];
end
end
///////////////////////////////////////////////////////////
////// EMULATOR ASYNCHRONOUS RAM TIMING
////
assign o_EMU_TIMING[4:3] = horizontal_counter[1:0];
assign o_EMU_TIMING[2:0] = ref_clock_counter_6;
endmodule

View File

@@ -1,320 +0,0 @@
module CHARRAM
(
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
input wire [4:0] i_EMU_TIMING,
input wire i_CHARCS_n,
input wire [14:0] i_CPUADDR,
inout wire [15:0] io_CPUDATA,
input wire i_CPURW,
input wire i_CPUUDS_n,
input wire i_CPULDS_n,
input wire [13:0] i_GFXADDR,
output reg [31:0] o_GFXDATA = 32'hFFFF
);
///////////////////////////////////////////////////////////
////// CHARRAM
////
/*
A1 MSB D A T A LSB
0 |---(8bit SEL0)---|---(8bit SEL1)---|
1 |---(8bit SEL2)---|---(8bit SEL3)---|
BIG ENDIAN
*/
//declare 32bit width CHARRAM
reg [13:0] CHARRAM_ADDRLATCH;
reg [7:0] CHARRAM_0_INLATCH;
reg [7:0] CHARRAM_1_INLATCH;
reg [7:0] CHARRAM_2_INLATCH;
reg [7:0] CHARRAM_3_INLATCH;
wire [31:0] CHARRAM_OUT;
reg CHARRAM_RD = 1'b1;
reg CHARRAM_WR = 1'b1;
reg CHARRAM_SEL0 = 1'b1;
reg CHARRAM_SEL1 = 1'b1;
reg CHARRAM_SEL2 = 1'b1;
reg CHARRAM_SEL3 = 1'b1;
reg [7:0] CHARRAMU_CPU_LATCH = 8'hF;
reg [7:0] CHARRAML_CPU_LATCH = 8'hF;
wire CHARRAM_CPU_LATCH_RD = i_CHARCS_n | ~i_CPURW;
assign io_CPUDATA[15:8] = ((i_CPUUDS_n | CHARRAM_CPU_LATCH_RD) == 1'b0) ? CHARRAMU_CPU_LATCH : {8{1'bZ}}; //UDS out
assign io_CPUDATA[7:0] = ((i_CPULDS_n | CHARRAM_CPU_LATCH_RD) == 1'b0) ? CHARRAML_CPU_LATCH : {8{1'bZ}}; //LDS out
RAM16k32 CHARRAM_ELEMENT
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_ADDR (CHARRAM_ADDRLATCH ),
.i_DIN ({CHARRAM_0_INLATCH, CHARRAM_1_INLATCH, CHARRAM_2_INLATCH, CHARRAM_3_INLATCH,}),
.o_DOUT (CHARRAM_OUT ),
.i_RD_n (CHARRAM_RD ),
.i_WR_n (CHARRAM_WR ),
.i_SEL0_n (CHARRAM_SEL0 ),
.i_SEL1_n (CHARRAM_SEL1 ),
.i_SEL2_n (CHARRAM_SEL2 ),
.i_SEL3_n (CHARRAM_SEL3 )
);
///////////////////////////////////////////////////////////
////// CHARACTER RAM INTERFACE STATE MACHINE
////
/*
EXECUTING S S S S S S S S S S S S S S S S S S S S S S S S S
0 0 0 0 0 1 2 3 0 0 0 0 0 0 0 0 0 4 5 6 0 0 0 0 0
MCLK 1 1
0 1 2 3 4 5 6 7 8 9 0 1
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
PIXEL ----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|
/DTACK ¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
CHAMPX1 ¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|_______|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
/RAS ____________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________ 15ns(LS14) delayed
/CAS ________________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|_______________|¯¯¯¯¯¯¯|___________ 15ns*4(LS14) + 25ns(220pF) = about 85ns delayed
>DRAM CPU/REFRESH >DRAM GFX DOUT >DRAM CPU/REFRESH >DRAM GFX DOU DRAM async access speed 150ns (TMS4416)
Automatically refreshes ROW ADDRESS during CPU/HV counter access cycle
DEVICE |---------(CPU)---------|---------(GFX)---------|---------(CPU)---------|---------(GFX)---------|
LATCHED CPU WR ¯¯¯¯¯¯¯¯¯¯¯¯|_______________________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|(WR VALID)-| |(WR VALID)-|
|(RD VALID)-| |(RD VALID)-|
| CHARRAM ADDR TM-A | CHARRAM ADDR TM-B |
>CHARRAM TM-A data latched by K005290
>CHARRAM data TM-B latched by K005290
*/
//declare states
localparam CHARRAM_ACC_S0 = 3'd0; //nop
localparam CHARRAM_ACC_S1 = 3'd1; //CS내려갔으면 어드레스 래치에 어드레스 넣기, RD면 RD=0, WR이면 INLATCH에 CPU데이터 넣고 WR=0
localparam CHARRAM_ACC_S2 = 3'd2; //RD면 RD=1, WR=1(SEL도 1로 복귀)
localparam CHARRAM_ACC_S3 = 3'd3; //CPU OUTLATCH에 데이터 넣기
localparam CHARRAM_ACC_S4 = 3'd4; //어드레스 래치에 어드레스 넣기, RD=0
localparam CHARRAM_ACC_S5 = 3'd5; //RD=1
localparam CHARRAM_ACC_S6 = 3'd6; //GFXDATA에 넣기
//state register
reg [2:0] CHARRAM_ACC_state = CHARRAM_ACC_S0;
//flow control
always @(posedge i_EMU_MCLK)
begin
case(i_EMU_TIMING[4:3])
2'd0: //pixel 0
begin
case(i_EMU_TIMING[2:0])
3'd0: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd1: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd2: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd3: CHARRAM_ACC_state <= CHARRAM_ACC_S1;
3'd4: CHARRAM_ACC_state <= CHARRAM_ACC_S2;
3'd5: CHARRAM_ACC_state <= CHARRAM_ACC_S3;
default: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
endcase
end
2'd1: //pixel 1
begin
case(i_EMU_TIMING[2:0])
3'd0: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd1: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd2: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd3: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd4: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd5: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
default: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
endcase
end
2'd2: //pixel 2
begin
case(i_EMU_TIMING[2:0])
3'd0: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd1: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd2: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd3: CHARRAM_ACC_state <= CHARRAM_ACC_S4;
3'd4: CHARRAM_ACC_state <= CHARRAM_ACC_S5;
3'd5: CHARRAM_ACC_state <= CHARRAM_ACC_S6;
default: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
endcase
end
2'd3: //pixel 3
begin
case(i_EMU_TIMING[2:0])
3'd0: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd1: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd2: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd3: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd4: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
3'd5: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
default: CHARRAM_ACC_state <= CHARRAM_ACC_S0;
endcase
end
endcase
end
//output control
always @(posedge i_EMU_MCLK)
begin
case(CHARRAM_ACC_state)
CHARRAM_ACC_S0: begin end
CHARRAM_ACC_S1:
begin
if(i_CHARCS_n == 1'b0)
begin
CHARRAM_ADDRLATCH <= i_CPUADDR[14:1]; //A1=0 CHACS1, A1=1 CHACS2
end
if(i_CPURW == 1'b1) //read
begin
if(i_CHARCS_n == 1'b0)
begin
if(i_CPUADDR[0] == 1'b0) //CHACS1
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAM_SEL0 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAM_SEL1 <= 1'b0;
end
CHARRAM_RD <= 1'b0;
end
else //CHACS2
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAM_SEL2 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAM_SEL3 <= 1'b0;
end
CHARRAM_RD <= 1'b0;
end
end
end
else //write
begin
if(i_CHARCS_n == 1'b0)
begin
if(i_CPUADDR[0] == 1'b0) //CHACS1
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAM_0_INLATCH <= io_CPUDATA[15:8];
CHARRAM_SEL0 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAM_1_INLATCH <= io_CPUDATA[7:0];
CHARRAM_SEL1 <= 1'b0;
end
CHARRAM_WR <= 1'b0;
end
else //CHACS2
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAM_2_INLATCH <= io_CPUDATA[15:8];
CHARRAM_SEL2 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAM_3_INLATCH <= io_CPUDATA[7:0];
CHARRAM_SEL3 <= 1'b0;
end
CHARRAM_WR <= 1'b0;
end
end
end
end
CHARRAM_ACC_S2:
begin
CHARRAM_SEL0 <= 1'b1;
CHARRAM_SEL1 <= 1'b1;
CHARRAM_SEL2 <= 1'b1;
CHARRAM_SEL3 <= 1'b1;
CHARRAM_WR <= 1'b1;
CHARRAM_RD <= 1'b1;
end
CHARRAM_ACC_S3:
begin
if(i_CPURW == 1'b1) //read
begin
if(i_CHARCS_n == 1'b0)
begin
if(i_CPUADDR[0] == 1'b0) //CHACS1
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAMU_CPU_LATCH <= CHARRAM_OUT[31:24];
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAML_CPU_LATCH <= CHARRAM_OUT[23:16];
end
end
else //CHACS2
begin
if(i_CPUUDS_n == 1'b0)
begin
CHARRAMU_CPU_LATCH <= CHARRAM_OUT[15:8];
end
if(i_CPULDS_n == 1'b0)
begin
CHARRAMU_CPU_LATCH <= CHARRAM_OUT[7:0];
end
end
end
end
end
CHARRAM_ACC_S4:
begin
CHARRAM_ADDRLATCH <= i_GFXADDR;
CHARRAM_SEL0 <= 1'b0;
CHARRAM_SEL1 <= 1'b0;
CHARRAM_SEL2 <= 1'b0;
CHARRAM_SEL3 <= 1'b0;
CHARRAM_RD <= 1'b0;
end
CHARRAM_ACC_S5:
begin
CHARRAM_SEL0 <= 1'b1;
CHARRAM_SEL1 <= 1'b1;
CHARRAM_SEL2 <= 1'b1;
CHARRAM_SEL3 <= 1'b1;
CHARRAM_RD <= 1'b1;
end
CHARRAM_ACC_S6:
begin
o_GFXDATA <= CHARRAM_OUT;
end
default: begin end
endcase
end
endmodule

View File

@@ -1,180 +0,0 @@
module SCROLLRAM
(
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
input wire [4:0] i_EMU_TIMING,
input wire i_VZCS_n,
input wire [10:0] i_CPUADDR,
inout wire [15:0] io_CPUDATA,
input wire i_CPURW,
input wire i_CPULDS_n,
input wire [10:0] i_GFXADDR,
output reg [7:0] o_GFXDATA = 8'hF
);
///////////////////////////////////////////////////////////
////// SCROLL RAM
////
reg [10:0] SCROLLRAM_ADDRLATCH;
reg [7:0] SCROLLRAM_INLATCH;
wire [7:0] SCROLLRAM_OUT;
reg SCROLLRAM_RD = 1'b1;
reg SCROLLRAM_WR = 1'b1;
reg [7:0] SCROLLRAM_CPU_LATCH = 8'hF;
wire SCROLLRAM_CPU_LATCH_RD = i_VZCS_n | ~i_CPURW;
assign io_CPUDATA[7:0] = (i_CPULDS_n | SCROLLRAM_CPU_LATCH_RD == 1'b0) ? SCROLLRAM_CPU_LATCH : {8{1'bZ}}; //LDS out
RAM2k8 SCROLLRAM_ELEMENT
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_ADDR (SCROLLRAM_ADDRLATCH ),
.i_DIN (SCROLLRAM_INLATCH ),
.o_DOUT (SCROLLRAM_OUT ),
.i_RD_n (SCROLLRAM_RD ),
.i_WR_n (SCROLLRAM_WR )
);
///////////////////////////////////////////////////////////
////// SCROLL RAM INTERFACE STATE MACHINE
////
/*
This state machine emulates original behavior of asynchronous ZURERAM(SCROLLRAM)
Consist of 6116 SRAM(access speed about 100-150ns) and a LS373 latch for CPU readout
*/
/*
Note: TM-A is scroll1 in MAME
TM-B is scroll2 in MAME
FETCHES HSCROLL(1 PIXEL ROW) VALUE WHEN VCLK = 1
EXECUTING S S S S S S S S S S S S
0 1 2 0 3 4 5 6 7 8 0 0
MCLK 0 1 2 3 4 5 0 1 2 3 4 5
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|
>SRAM DOUT >SRAM DOUT >SRAM DOUT >SRAM DOUT SRAM async access speed >150ns (2128-15 on every PCB)
TIME1 ___________________|¯¯¯|___________________|¯¯¯|____________
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
VCLK ___________|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
ADDR |-------(TM-A LO)-------|-------(TM-A HI)-------|
DEVICE |---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|
| TM-A LO | | TM-A HI |
FETCHES VSCROLL(8 PIXEL COLUMN) VALUE WHEN VCLK = 0
(TM-A for 4H = 0, TM-B for 4H = 1)
1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|___|¯¯¯|___|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|___|¯¯¯|___|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|
TIME1 ___________________|¯¯¯|___________________|¯¯¯|___________________|¯¯¯|___________________|¯¯¯|____________
TIME2 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯
VCLK ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
SCRLATCH¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|
SCRADDR --(TM-A)---|--------------------(TM-B)---------------------|--------------------(TM-A)---------------------|
DEVICE ---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|---(CPU)---|---(GFX)---|
VRAMADDR--(TM-B)---|--------------------(TM-A)---------------------|--------------------(TM-B)---------------------|
t0 t1 t2
0. HSCROLL values for TM-A and TM-B are latched when VCLK = 1
t0
1. MUX provides TM-A VSCROLL address when 4H = 0 & VCLK = 0
2. 005291 latches TM-A VSCROLL value at posedge of ~(1H & 2H)
3. Then TM-A VSCROLL value will be valid during next 4px-cycle
4. In this next 4px-cycle, 005291 provides previously latched(at VCLK = 0) TM-A HSCROLL value
5. ?????
6. PROFIT!!
t1
1. Again, 005291 latches TM-A VSCROLL value at posedge of ~(1H & 2H) since MUX provided TM-B VSCROLL address
2. Then TM-B VSCROLL value will be valid during next 4px-cycle
3. In this next 4px-cycle, 005291 provides previously latched(at VCLK = 0) TM-B HSCROLL value
4. ?????
5. PROFIT!!
*/
//declare states
localparam SCROLL_ACC_S0 = 4'd0; //nop
localparam SCROLL_ACC_S1 = 4'd1; //스크롤램 어드레스 래치에다 CPU 어드레스 넣고, RD=0
localparam SCROLL_ACC_S2 = 4'd2; //RD=1
localparam SCROLL_ACC_S3 = 4'd3; //출력값 CPU래치에 넣기(TIME1 LS373 load)
localparam SCROLL_ACC_S4 = 4'd4; //만약 이때 CPU 비동기 쓰기신호가 내려가있으면 데이터를 INLATCH에 넣고 WR=0(TIME2 6116 /write)
localparam SCROLL_ACC_S5 = 4'd5; //WR=1
localparam SCROLL_ACC_S6 = 4'd6; //어드레스 래치에 현재 스크롤좌표 넣고, RD=0
localparam SCROLL_ACC_S7 = 4'd7; //RD=1
localparam SCROLL_ACC_S8 = 4'd8; //스크롤값 출력을 GFX래치에 넣기
//state register
reg [3:0] SCROLL_ACC_state = SCROLL_ACC_S11;
//flow control
always @(posedge i_EMU_MCLK)
begin
if(i_EMU_TIMING[3] == 1'b0) //pixel 0
begin
case(i_EMU_TIMING[2:0])
3'd0: SCROLL_ACC_state <= SCROLL_ACC_S2;
3'd1: SCROLL_ACC_state <= SCROLL_ACC_S0;
3'd2: SCROLL_ACC_state <= SCROLL_ACC_S3;
3'd3: SCROLL_ACC_state <= SCROLL_ACC_S4;
3'd4: SCROLL_ACC_state <= SCROLL_ACC_S5;
3'd5: SCROLL_ACC_state <= SCROLL_ACC_S6;
default: SCROLL_ACC_state <= SCROLL_ACC_S0;
endcase
end
else //pixel 1
begin
case(i_EMU_TIMING[2:0])
3'd0: SCROLL_ACC_state <= SCROLL_ACC_S7;
3'd1: SCROLL_ACC_state <= SCROLL_ACC_S8;
3'd2: SCROLL_ACC_state <= SCROLL_ACC_S0;
3'd3: SCROLL_ACC_state <= SCROLL_ACC_S0;
3'd4: SCROLL_ACC_state <= SCROLL_ACC_S0;
3'd5: SCROLL_ACC_state <= SCROLL_ACC_S1;
default: SCROLL_ACC_state <= SCROLL_ACC_S0;
endcase
end
end
//output control
always @(posedge i_EMU_MCLK)
begin
case(SCROLL_ACC_state)
SCROLL_ACC_S0: begin end
SCROLL_ACC_S1: begin SCROLLRAM_ADDRLATCH <= i_CPUADDR[10:0]; SCROLLRAM_RD <= 1'b0; end
SCROLL_ACC_S2: begin SCROLLRAM_RD <= 1'b1; end
SCROLL_ACC_S3: begin SCROLLRAM_CPU_LATCH <= SCROLLRAM_OUT; end
SCROLL_ACC_S4: begin if((i_VZCS_n | i_CPURW | i_CPULDS_n) == 1'b0) begin SCROLLRAM_WR <= 1'b0; SCROLLRAM_INLATCH <= io_CPUDATA[7:0]; end end
SCROLL_ACC_S5: begin SCROLLRAM_WR <= 1'b1; end
SCROLL_ACC_S6: begin SCROLLRAM_ADDRLATCH <= i_GFXADDR; SCROLLRAM_RD <= 1'b0; end
SCROLL_ACC_S7: begin SCROLLRAM_RD <= 1'b1; end
SCROLL_ACC_S8: begin o_GFXDATA <= SCROLLRAM_OUT; end
default: begin end
endcase
end
endmodule

View File

@@ -1,295 +0,0 @@
module VRAM
(
input wire i_EMU_MCLK, //36.864(PLL 36.868687)
input wire [4:0] i_EMU_TIMING,
input wire i_VCS1_n,
input wire i_VCS2_n,
input wire [11:0] i_CPUADDR,
inout wire [15:0] io_CPUDATA,
input wire i_CPURW,
input wire i_CPUUDS_n,
input wire i_CPULDS_n,
input wire [11:0] i_GFXADDR,
output reg [15:0] o_VRAM1GFXDATA = 16'hFF,
output reg [7:0] o_VRAM2GFXDATA = 8'hF
);
///////////////////////////////////////////////////////////
////// VRAM
////
//declare 16bit width VRAM 1
reg [11:0] VRAM1_ADDRLATCH;
reg [7:0] VRAM1_0_INLATCH;
reg [7:0] VRAM1_1_INLATCH;
wire [15:0] VRAM1_OUT;
reg VRAM1_RD = 1'b1;
reg VRAM1_WR = 1'b1;
reg VRAM1_SEL0 = 1'b1;
reg VRAM1_SEL1 = 1'b1;
reg [7:0] VRAM1U_CPU_LATCH = 8'hF;
reg [7:0] VRAM1L_CPU_LATCH = 8'hF;
wire VRAM1_CPU_LATCH_RD = i_VCS1_n | ~i_CPURW;
assign io_CPUDATA[15:8] = ((i_CPUUDS_n | VRAM1_CPU_LATCH_RD) == 1'b0) ? VRAM1U_CPU_LATCH : {8{1'bZ}}; //UDS out
assign io_CPUDATA[7:0] = ((i_CPULDS_n | VRAM1_CPU_LATCH_RD) == 1'b0) ? VRAM1L_CPU_LATCH : {8{1'bZ}}; //LDS out
RAM4k16 VRAM1_ELEMENT
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_ADDR (VRAM1_ADDRLATCH ),
.i_DIN ({VRAM1_0_INLATCH, VRAM1_1_INLATCH}),
.o_DOUT (VRAM1_OUT ),
.i_RD_n (VRAM1_RD ),
.i_WR_n (VRAM1_WR ),
.i_SEL0_n (VRAM1_SEL0 ),
.i_SEL1_n (VRAM1_SEL1 )
);
//declare 8bit width VRAM 2
reg [11:0] VRAM2_ADDRLATCH;
reg [7:0] VRAM2_INLATCH;
wire [7:0] VRAM2_OUT;
reg VRAM2_RD = 1'b1;
reg VRAM2_WR = 1'b1;
reg [7:0] VRAM2_CPU_LATCH = 8'hF;
wire VRAM2_CPU_LATCH_RD = i_VCS2_n | ~i_CPURW;
assign io_CPUDATA[7:0] = (i_CPULDS_n | VRAM2_CPU_LATCH_RD == 1'b0) ? VRAM2_CPU_LATCH : {8{1'bZ}}; //LDS out
RAM4k8 VRAM2_ELEMENT
(
.i_EMU_MCLK (i_EMU_MCLK ),
.i_ADDR (VRAM2_ADDRLATCH ),
.i_DIN (VRAM2_INLATCH ),
.o_DOUT (VRAM2_OUT ),
.i_RD_n (VRAM2_RD ),
.i_WR_n (VRAM2_WR )
);
///////////////////////////////////////////////////////////
////// VIDEO RAM INTERFACE STATE MACHINE
////
/*
EXECUTING S S S S S S S S S S S S S S S S S S S S S S S S
0 0 1 0 2 3 4 0 0 0 0 0 0 0 0 0 5 6 7 0 0 0 0 0
MCLK
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
CLK18M ¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|¯|_|
CLK9M ¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|___|¯¯¯|
CLK6M ¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯|___|
PIXEL ----(7)----|----(0)----|----(1)----|----(2)----|----(3)----|----(4)----|----(5)----|----(6)----|----(7)----|
/DTACK ¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯S0¯¯S1¯¯S2¯¯S3¯¯S4¯|_w___w__S5__S6|¯S7¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
>SRAM CPU DIN >SRAM GFX DOUT >SRAM CPU DOUT >SRAM GFX DOUT SRAM async access speed 100ns (TC5533-P on every PCB)
VRTIME ¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|___|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 6264 CE2 is always 1 in cpu access cycle
DEVICE |---------(CPU)---------|---------(GFX)---------|---------(CPU)---------|---------(GFX)---------|
|(RD VALID)-| |(RD VALID)-| ext. gates allow RD during pixel 0 and 1 cycles
|WRVAL| |WRVAL| ext. gates allow WR during pixel 0 cycle
| VRAM ADDR TM-A | VRAM ADDR TM-B |
>VRAM ADDR TM-A latched by LS273 at /2H
>CHARRAM TM-A line data latched
*/
//declare states
localparam VRAM_ACC_S0 = 3'd0; //nop
localparam VRAM_ACC_S1 = 3'd1; //CS내려갔으면 어드레스 래치에 어드레스 넣기
localparam VRAM_ACC_S2 = 3'd2; //WR이면 INLATCH에 CPU데이터 넣고 WR=0, RD면 SEL선택하고 RD=0
localparam VRAM_ACC_S3 = 3'd3; //WR=1(SEL도 1로 복귀), RD=1
localparam VRAM_ACC_S4 = 3'd4; //VRAM_OUT데이터 CPULATCH에 넣기
localparam VRAM_ACC_S5 = 3'd5; //어드레스 래치에 스크롤 어드레스 넣기, RD=0
localparam VRAM_ACC_S6 = 3'd6; //RD=1
localparam VRAM_ACC_S7 = 3'd7; //VRAM_OUT데이터 GFX_LATCH에 넣기
//state register
reg [2:0] VRAM_ACC_state = VRAM_ACC_S0;
//flow control
always @(posedge i_EMU_MCLK)
begin
case(i_EMU_TIMING[4:3])
2'd0: //pixel 0
begin
case(i_EMU_TIMING[2:0])
4'd0: VRAM_ACC_state <= VRAM_ACC_S1;
4'd1: VRAM_ACC_state <= VRAM_ACC_S0;
4'd2: VRAM_ACC_state <= VRAM_ACC_S2;
4'd3: VRAM_ACC_state <= VRAM_ACC_S3;
4'd4: VRAM_ACC_state <= VRAM_ACC_S0;
4'd5: VRAM_ACC_state <= VRAM_ACC_S0;
default: VRAM_ACC_state <= VRAM_ACC_S0;
endcase
end
2'd1: //pixel 1
begin
case(i_EMU_TIMING[2:0])
4'd0: VRAM_ACC_state <= VRAM_ACC_S0;
4'd1: VRAM_ACC_state <= VRAM_ACC_S0;
4'd2: VRAM_ACC_state <= VRAM_ACC_S0;
4'd3: VRAM_ACC_state <= VRAM_ACC_S0;
4'd4: VRAM_ACC_state <= VRAM_ACC_S0;
4'd5: VRAM_ACC_state <= VRAM_ACC_S0;
default: VRAM_ACC_state <= VRAM_ACC_S0;
endcase
end
2'd2: //pixel 2
begin
case(i_EMU_TIMING[2:0])
4'd0: VRAM_ACC_state <= VRAM_ACC_S0;
4'd1: VRAM_ACC_state <= VRAM_ACC_S0;
4'd2: VRAM_ACC_state <= VRAM_ACC_S5;
4'd3: VRAM_ACC_state <= VRAM_ACC_S6;
4'd4: VRAM_ACC_state <= VRAM_ACC_S7;
4'd5: VRAM_ACC_state <= VRAM_ACC_S0;
default: VRAM_ACC_state <= VRAM_ACC_S0;
endcase
end
2'd3: //pixel 3
begin
case(i_EMU_TIMING[2:0])
4'd0: VRAM_ACC_state <= VRAM_ACC_S0;
4'd1: VRAM_ACC_state <= VRAM_ACC_S0;
4'd2: VRAM_ACC_state <= VRAM_ACC_S0;
4'd3: VRAM_ACC_state <= VRAM_ACC_S0;
4'd4: VRAM_ACC_state <= VRAM_ACC_S0;
4'd5: VRAM_ACC_state <= VRAM_ACC_S0;
default: VRAM_ACC_state <= VRAM_ACC_S0;
endcase
end
endcase
end
//output control
always @(posedge i_EMU_MCLK)
begin
case(VRAM_ACC_state)
VRAM_ACC_S0: begin end
VRAM_ACC_S1:
begin
if(i_VCS1_n == 1'b0)
begin
VRAM1_ADDRLATCH <= i_CPUADDR;
end
if(i_VCS2_n == 1'b0)
begin
VRAM2_ADDRLATCH <= i_CPUADDR;
end
end
VRAM_ACC_S2:
begin
if(i_CPURW == 1'b1) //read
begin
if(i_VCS1_n == 1'b0)
begin
if(i_CPUUDS_n == 1'b0)
begin
VRAM1_SEL0 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
VRAM1_SEL1 <= 1'b0;
end
VRAM1_RD <= 1'b0;
end
if(i_VCS2_n == 1'b0)
begin
VRAM2_WR <= 1'b0;
end
end
else //write
begin
if(i_VCS1_n == 1'b0)
begin
if(i_CPUUDS_n == 1'b0)
begin
VRAM1_0_INLATCH <= io_CPUDATA[15:8];
VRAM1_SEL0 <= 1'b0;
end
if(i_CPULDS_n == 1'b0)
begin
VRAM1_1_INLATCH <= io_CPUDATA[7:0];
VRAM1_SEL1 <= 1'b0;
end
VRAM1_WR <= 1'b0;
end
if(i_VCS2_n== 1'b0)
begin
if(i_CPULDS_n == 1'b0)
begin
VRAM2_INLATCH <= io_CPUDATA[7:0];
end
VRAM2_WR <= 1'b0;
end
end
end
VRAM_ACC_S3:
begin
VRAM1_SEL0 <= 1'b1;
VRAM1_SEL1 <= 1'b1;
VRAM1_WR <= 1'b1;
VRAM2_WR <= 1'b1;
VRAM1_RD <= 1'b1;
VRAM2_RD <= 1'b1;
end
VRAM_ACC_S4:
begin
if(i_VCS1_n | ~i_CPURW == 1'b0)
begin
if(i_CPUUDS_n == 1'b0)
begin
VRAM1U_CPU_LATCH <= VRAM1_OUT[15:8];
end
if(i_CPULDS_n == 1'b0)
begin
VRAM1L_CPU_LATCH <= VRAM1_OUT[7:0];
end
end
if(i_VCS2_n | ~i_CPURW == 1'b0)
begin
VRAM2_CPU_LATCH <= VRAM2_OUT;
end
end
VRAM_ACC_S5:
begin
VRAM1_ADDRLATCH <= i_GFXADDR;
VRAM2_ADDRLATCH <= i_GFXADDR;
VRAM1_SEL0 <= 1'b0;
VRAM1_SEL1 <= 1'b0;
VRAM1_RD <= 1'b0;
VRAM2_RD <= 1'b0;
end
VRAM_ACC_S6:
begin
VRAM1_SEL0 <= 1'b1;
VRAM1_SEL1 <= 1'b1;
VRAM1_RD <= 1'b1;
VRAM2_RD <= 1'b1;
end
VRAM_ACC_S7:
begin
o_VRAM1GFXDATA <= VRAM1_OUT;
o_VRAM2GFXDATA <= VRAM2_OUT;
end
endcase
end
endmodule

View File

@@ -1,101 +0,0 @@
/*
8*4416 16k*32 DRAM ELEMENT
*/
module RAM16k32
(
input wire i_EMU_MCLK,
input wire [13:0] i_ADDR,
input wire [31:0] i_DIN,
output reg [31:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n,
input wire i_SEL0_n,
input wire i_SEL1_n,
input wire i_SEL2_n,
input wire i_SEL3_n
);
/*
A1 MSB D A T A LSB
0 |---(8bit SEL0)---|---(8bit SEL1)---|
1 |---(8bit SEL2)---|---(8bit SEL3)---|
*/
//A=0, upper 8 bit
reg [7:0] RAM16k8_0 [16383:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL0_n == 1'b0)
begin
o_DOUT[31:24] <= RAM16k8_0[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL0_n == 1'b0)
begin
RAM16k8_0[i_ADDR] <= i_DIN[31:24];
end
end
//A=0, lower 8 bit
reg [7:0] RAM16k8_1 [16383:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL1_n == 1'b0)
begin
o_DOUT[23:16] <= RAM16k8_1[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL1_n == 1'b0)
begin
RAM16k8_1[i_ADDR] <= i_DIN[23:16];
end
end
//A=1, upper 8 bit
reg [7:0] RAM16k8_2 [16383:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL2_n == 1'b0)
begin
o_DOUT[15:8] <= RAM16k8_2[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL2_n == 1'b0)
begin
RAM16k8_2[i_ADDR] <= i_DIN[15:8];
end
end
//A=1, lower 8 bit
reg [7:0] RAM16k8_3 [16383:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL3_n == 1'b0)
begin
o_DOUT[7:0] <= RAM16k8_3[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL3_n == 1'b0)
begin
RAM16k8_3[i_ADDR] <= i_DIN[7:0];
end
end
endmodule

View File

@@ -1,62 +0,0 @@
/*
2*6264 4k*16 SRAM ELEMENT
*/
module RAM4k16
(
input wire i_EMU_MCLK,
input wire [11:0] i_ADDR,
input wire [15:0] i_DIN,
output reg [15:0] o_DOUT,
input wire i_WR_n,
input wire i_RD_n,
input wire i_SEL0_n,
input wire i_SEL1_n
);
/*
MSB D A T A LSB
|---(8bit SEL0)---|---(8bit SEL1)---|
*/
//upper 8 bit
reg [7:0] RAM4k8_0 [4095:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL0_n == 1'b0)
begin
o_DOUT[15:8] <= RAM4k8_0[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL0_n == 1'b0)
begin
RAM4k8_0[i_ADDR] <= i_DIN[15:8];
end
end
//lower 8 bit
reg [7:0] RAM4k8_1 [4095:0];
always @(negedge i_EMU_MCLK) //read
begin
if(i_RD_n | i_SEL1_n == 1'b0)
begin
o_DOUT[7:0] <= RAM4k8_1[i_ADDR];
end
end
always @(negedge i_EMU_MCLK)
begin
if(i_WR_n | i_SEL1_n == 1'b0)
begin
RAM4k8_1[i_ADDR] <= i_DIN[7:0];
end
end
endmodule