module main(
// clocks
input fclk,
output clkz_out,
input clkz_in,
// z80
input iorq_n,
input mreq_n,
input rd_n,
input wr_n,
input m1_n,
input rfsh_n,
input int_n,
input nmi_n,
input wait_n,
output res,
inout [7:0] d,
output [15:0] a,
// zxbus and related
output csrom,
output romoe_n,
output romwe_n,
output rompg0_n,
output dos_n, // aka rompg1
output rompg2,
output rompg3,
output rompg4,
input iorqge1,
input iorqge2,
output iorq1_n,
output iorq2_n,
// DRAM
inout [15:0] rd,
output [9:0] ra,
output rwe_n,
output rucas_n,
output rlcas_n,
output rras0_n,
output rras1_n,
// video
output [1:0] vred,
output [1:0] vgrn,
output [1:0] vblu,
output vhsync,
output vvsync,
output vcsync,
// AY control and audio/tape
input ay_clk,
output ay_bdir,
output ay_bc1,
output reg beep,
// IDE
input [2:0] ide_a,
input [15:0] ide_d,
output ide_dir,
input ide_rdy,
output ide_cs0_n,
output ide_cs1_n,
output ide_rs_n,
output ide_rd_n,
output ide_wr_n,
// VG93 and diskdrive
output reg vg_clk,
output vg_cs_n,
output vg_res_n,
input vg_hrdy,
input vg_rclk,
input vg_rawr,
input [1:0] vg_a, // disk drive selection
input vg_wrd,
input vg_side,
input step,
input vg_sl,
input vg_sr,
input vg_tr43,
input rdat_b_n,
input vg_wf_de,
input vg_drq,
input vg_irq,
input vg_wd,
// serial links (atmega-fpga, sdcard)
output sdcs_n,
output sddo,
output sdclk,
input sddi,
input spics_n,
input spick,
input spido,
output spidi,
output reg spiint_n
);
//--Dummy----------------------------------------------------------------------
assign iorq1_n = 1'b1;
assign iorq2_n = 1'b1;
assign res = 1'b1;
assign ay_bdir = 1'b0;
assign ay_bc1 = 1'b0;
assign vg_cs_n = 1'b1;
assign vg_res_n = 1'b0;
assign ide_dir = 1'b1;
assign ide_rs_n = 1'b0;
assign ide_cs0_n = 1'b1;
assign ide_cs1_n = 1'b1;
assign ide_rd_n = 1'b1;
assign ide_wr_n = 1'b1;
assign a[15:14] = 2'b00;
//--INT---------------------------------------------------------------------------
reg enable_covox_int; initial enable_covox_int = 1'b0;
reg enable_frame_int; initial enable_frame_int = 1'b0;
always @(posedge fclk)
begin
if ( enable_covox_int )
spiint_n <= cvx_ptr_diff[3]|main_osc[7];
else if ( enable_frame_int )
spiint_n <= vtxtscr;
else
spiint_n <= 1'b1;
end
//--clocks--Z80_clk--VG_clk--COVOX---------------------------------------------
reg [9:0] main_osc;
reg [2:0] vgclk_div7;
reg [7:0] covox [15:0]; initial covox[0] = 8'h7f;
reg [8:0] qe; initial qe = 9'h0ff;
reg [3:0] cvx_ptr_out; initial cvx_ptr_out = 4'd0;
reg [3:0] cvx_ptr_in; initial cvx_ptr_in = 4'd0;
wire [3:0] cvx_ptr_iinc;
wire [3:0] cvx_ptr_diff;
assign cvx_ptr_iinc = cvx_ptr_in + 4'd1;
assign cvx_ptr_diff = cvx_ptr_in - cvx_ptr_out;
always @(posedge fclk)
begin
//
if ( { 1'b1, covox[cvx_ptr_out] } >= qe )
begin
beep <= 1'b1;
qe <= 9'h1ff - { 1'b1, covox[cvx_ptr_out] } + qe;
end
else
begin
beep <= 1'b0;
qe <= 9'h000 - { 1'b1, covox[cvx_ptr_out] } + qe;
end
//
if ( main_osc[7:0] == 8'hff )
begin
if ( cvx_ptr_in !== cvx_ptr_out )
cvx_ptr_out <= cvx_ptr_out + 4'd1;
end
//
if ( main_osc[1:0]==2'b00 )
begin
if ( vgclk_div7[2:1] == 2'b11 )
begin
vgclk_div7 <= 3'd0;
vg_clk <= ~vg_clk;
end
else
vgclk_div7 <= vgclk_div7 + 3'd1;
end
//
main_osc <= main_osc + 10'd1;
//
end
assign clkz_out = main_osc[2]; // 3.5 MHz
//--Video----------------------------------------------------------------------
// character image - 6x8
// character size - 6x10
// col x row - 53x25 (318x250)
// fullscreen test - 360x288
localparam HTXTS_END = 9'd416;
localparam CSYNC_CUT = 9'd415;
localparam CSYNC_CUT2 = 9'd394; // 9'd395; // 9'd382;
localparam HSYNC_BEG = 9'd0;
localparam HSYNC_BEG2 = 9'd447;
localparam HSYNC_END = 9'd33;
localparam HSYNC_END2 = 9'd52; // 9'd53;
localparam HTXTS_BEG = 9'd98;
localparam HMAX = 9'd447;
localparam VTXTS_END = 9'd293;
localparam VSYNC_BEG = 9'd0;
localparam VSYNC_END = 9'd2;
localparam VTXTS_BEG = 9'd43;
localparam VMAX = 9'd319;
localparam HBORD_BEG = 9'd77;
localparam HBORD_END = 9'd437;
localparam VBORD_BEG = 9'd24;
localparam VBORD_END = 9'd312;
// GgRrBb
localparam BLACK = 6'b000000;
localparam GRAY_1 = 6'b010101;
localparam GRAY_2 = 6'b101010;
localparam WHITE = 6'b111111;
localparam BLUE_3 = 6'b000011;
localparam RED_3 = 6'b001100;
localparam MAGENTA_3 = 6'b001111;
localparam GREEN_3 = 6'b110000;
localparam CYAN_3 = 6'b110011;
localparam YELLOW_3 = 6'b111100;
localparam BLUE_2 = 6'b000010;
localparam RED_2 = 6'b001000;
localparam MAGENTA_2 = 6'b001010;
localparam GREEN_2 = 6'b100000;
localparam CYAN_2 = 6'b100010;
localparam YELLOW_2 = 6'b101000;
localparam BLUE_H = 6'b010110;
localparam RED_H = 6'b011001;
localparam MAGENTA_H = 6'b011010;
localparam GREEN_H = 6'b100101;
localparam CYAN_H = 6'b100110;
localparam YELLOW_H = 6'b101001;
reg [8:0] hcount; initial hcount = 9'd0;
reg [2:0] pixptr;
reg [8:0] vcount; initial vcount = 9'd0;
reg [5:0] hcharcount;
wire [2:0] vcharline;
reg [10:0] voffset;
reg [3:0] vcharlinecount;
reg hsync; initial hsync = 1'b1;
reg htxtscr; initial htxtscr = 1'b0;
reg vsync; initial vsync = 1'b1;
reg vtxtscr; initial vtxtscr = 1'b0;
reg csync; initial csync = 1'b1;
wire [10:0] video_addr;
wire [7:0] charcode0, charcode1, charcode2;
wire [7:0] charcode;
wire [7:0] attrcode0, attrcode1, attrcode2;
wire [7:0] attrcode;
wire [5:0] charpix;
wire pixel;
wire [5:0] fcolor, bcolor, image_color;
reg [5:0] color;
wire fontenable;
reg [8:0] hmouse, vmouse;
wire mouse_here, mouse_i, mouse_image, mouse_m, mouse_mask;
reg vgaff, nextline;
reg hbord; initial hbord = 1'b0;
reg vbord; initial vbord = 1'b0;
reg circle; initial circle = 1'b0;
reg uhole; initial uhole = 1'b0;
reg hhole; initial hhole = 1'b0;
reg vhole; initial vhole = 1'b0;
reg [1:0] bcdir; initial bcdir = 2'b00;
reg [1:0] scdir; initial scdir = 2'b00;
reg [3:0] hsetka, vsetka;
reg [4:0] hchess, vchess;
reg [1:0] hchss3;
reg [2:0] cband;
reg [6:0] bccount;
reg [4:0] sccount;
reg [6:0] schcnt;
wire [6:0] cb_val;
wire [4:0] cs_val;
reg [2:0] clr3;
always @(posedge fclk)
begin
//
if ( {(main_osc[1]&scr_tv_mode),main_osc[0]}==2'h0 )
begin
if ( scr_mode==2'h0 )
color <= (htxtscr & vtxtscr) ? ( (mouse_image) ? ~image_color : image_color ) : BLACK;
else if ( hbord & vbord )
case ( scr_mode )
3'h2:
color <= (hchess[0]^vchess[0]) ? WHITE : BLACK;
3'h3:
case (vchess)
5'd0, 5'd19:
if (vsetka==5'd14)
color <= GRAY_2;
else if (hchess[0])
color <= WHITE;
else
color <= BLACK;
5'd5, 5'd6:
case (cband)
3'd0: color <= GRAY_2;
3'd1: color <= YELLOW_H;
3'd2: color <= CYAN_H;
3'd3: color <= GREEN_H;
3'd4: color <= MAGENTA_H;
3'd5: color <= RED_H;
3'd6: color <= BLUE_H;
3'd7: color <= GRAY_1;
endcase
5'd13, 5'd14:
case (cband)
3'd0: color <= GRAY_2;
3'd1: color <= YELLOW_2;
3'd2: color <= CYAN_2;
3'd3: color <= GREEN_2;
3'd4: color <= MAGENTA_2;
3'd5: color <= RED_2;
3'd6: color <= BLUE_2;
3'd7: color <= BLACK;
endcase
default
begin
if (uhole)
begin
if (pixel)
color <= GRAY_2;
else
color <= GRAY_1;
end
else if ( (circle) && !(hhole&vhole) )
case (vchess)
5'd2, 5'd17:
if ( (hchess==5'd2) || (hchess==5'd3) || (hchess==5'd20) || (hchess==5'd21) )
begin
if (hcount[0])
color <= GRAY_2;
else
color <= GRAY_1;
end
else
color <= GRAY_2;
5'd3:
if ( (hchess==5'd2) || ((hchess==5'd3) && (hsetka!=5'd14))
|| (hchess==5'd20) || ((hchess==5'd21) && (hsetka!=5'd14)) )
begin
if (hcount[0]^vcount[0])
color <= GRAY_1;
else
color <= GRAY_2;
end
else
color <= GRAY_2;
5'd7:
case (cband)
//3'd0: color <= WHITE;
3'd1: color <= WHITE;
3'd2: color <= BLACK;
3'd3: color <= GRAY_1;
3'd4: color <= GRAY_2;
3'd5: color <= WHITE;
3'd6: color <= BLACK;
//3'd7: color <= BLACK;
endcase
5'd8:
if (hcount[3])
color <= MAGENTA_H;
else
color <= GREEN_H;
5'd9, 5'd10:
if ( (hcount[8]) ^ (vchess[0]) ^ ( (hchess==5'd4) && (hsetka==4'd14) ) )
color <= GRAY_2;
else
color <= BLACK;
5'd11:
if (hcount[3])
color <= RED_H;
else
color <= CYAN_H;
5'd12:
if (hcount[0])
color <= GRAY_2;
else
color <= GRAY_1;
5'd15:
if ( (hchess[0]) && (schcnt==6'd63) )
color <= BLACK;
else
color <= GRAY_2;
5'd16:
if ( (hchess==5'd2) || ((hchess==5'd3) &&(hsetka!=4'd14))
|| (hchess==5'd20) || ((hchess==5'd21)&&(hsetka!=4'd14)) )
begin
if (hcount[0]^vcount[0])
color <= GRAY_2;
else
color <= GRAY_1;
end
else
color <= GRAY_2;
default:
color <= GRAY_2;
endcase
else
color <= ( (hsetka==4'd14) || (vsetka==4'd14) ) ? GRAY_2 : GRAY_1;
end
endcase
3'h4: case (cband)
3'd0: color <= GRAY_2;
3'd1: color <= YELLOW_2;
3'd2: color <= CYAN_2;
3'd3: color <= GREEN_2;
3'd4: color <= MAGENTA_2;
3'd5: color <= RED_2;
3'd6: color <= BLUE_2;
3'd7: color <= BLACK;
endcase
3'h5: if (vchess[4]==1'b0)
begin
if (vchess!=5'd15)
case (cband)
3'd0: color <= GRAY_2;
3'd1: color <= YELLOW_2;
3'd2: color <= CYAN_2;
3'd3: color <= GREEN_2;
3'd4: color <= MAGENTA_2;
3'd5: color <= RED_2;
3'd6: color <= BLUE_2;
3'd7: color <= BLACK;
endcase
else
case (cband)
3'd0: color <= BLUE_2;
3'd1: color <= BLACK;
3'd2: color <= MAGENTA_2;
3'd3: color <= BLACK;
3'd4: color <= CYAN_2;
3'd5: color <= BLACK;
3'd6: color <= GRAY_2;
3'd7: color <= BLACK;
endcase
end
else
case (cband)
3'd0: color <= WHITE;
3'd1: color <= YELLOW_2;
3'd2: color <= CYAN_2;
3'd3: color <= GREEN_2;
3'd4: color <= MAGENTA_2;
3'd5: color <= RED_2;
3'd6: color <= BLUE_2;
3'd7: color <= BLACK;
endcase
3'h6: begin
if ( (vcount[2:0]==3'd4) || (hcount[2:0]==3'd1) )
begin
color[0] <= clr3[0];
color[1] <= clr3[0];
color[2] <= clr3[1];
color[3] <= clr3[1];
color[4] <= clr3[2];
color[5] <= clr3[2];
end
else
color <= BLACK;
end
default: color <= (hcount[0]^vcount[0]) ? WHITE : BLACK;
endcase
else
color <= BLACK;
hmouse <= hcount - scr_mouse_x;
if ( ~htxtscr )
begin
hcharcount <= 6'h00;
pixptr <= 3'd0;
end
else
begin
if ( pixptr==3'd5 )
begin
pixptr <= 3'd0;
hcharcount <= hcharcount + 6'h01;
end
else
pixptr <= pixptr + 3'd1;
end
if ( hcount==HMAX )
hcount <= 9'd0;
else
hcount <= hcount + 9'd1;
if ( hcount==HTXTS_END )
htxtscr <= 1'b0;
else if ( hcount==HTXTS_BEG )
htxtscr <= 1'b1;
if ( hcount==HSYNC_BEG )
begin
if ( scr_tv_mode ) hsync <= 1'b1;
vgaff <= scr_tv_mode | ~vgaff;
if ( vgaff )
begin
if ( scr_tv_mode ) csync <= 1'b1;
nextline <= 1'b1;
end
end
if ( (~scr_tv_mode) && (hcount==HSYNC_BEG2) )
begin
hsync <= 1'b1;
if ( vgaff ) csync <= 1'b1;
end
if ( (~scr_tv_mode) && (hcount==HSYNC_END2) )
begin
hsync <= 1'b0;
if ( !vsync )
csync <= 1'b0;
end
if ( scr_tv_mode && (hcount==HSYNC_END) )
begin
hsync <= 1'b0;
if ( !vsync )
csync <= 1'b0;
end
if (scr_tv_mode)
begin
if (hcount==CSYNC_CUT)
csync <= 1'b0;
end
else if ( (vgaff) && (hcount==CSYNC_CUT2) )
csync <= 1'b0;
if ( ((hchess==5'd0) || (hchess==5'd18)) && (hsetka==4'd13) )
schcnt <= 6'd0;
else if (schcnt!=6'd63)
schcnt <= schcnt+6'd1;
if ( hcount==HBORD_BEG )
begin
hbord <= 1'b1;
hsetka <= 4'd0;
hchess <= 5'd0;
hchss3 <= 2'd0;
cband <= 3'd0;
end
else
begin
if ( hsetka==4'd14 )
begin
hsetka <= 4'd0;
hchess <= hchess+5'd1;
if ( hchss3==2'd2 )
begin
hchss3 <= 2'd0;
cband <= cband+3'd1;
end
else
hchss3 <= hchss3+2'd1;
end
else
hsetka <= hsetka+4'd1;
if ( hcount==HBORD_END ) hbord <= 1'b0;
end
if ( !((vcount[2:0]==3'd0)&&vgaff) && (hcount==9'd0) )
clr3 <= { clr3[1:0], clr3[2] };
else if (hcount[2:0]==3'd5)
clr3 <= { clr3[1:0], clr3[2] };
end
//
if ( nextline )
begin
nextline <= 1'b0;
if ( ~vtxtscr )
begin
voffset <= 11'd0;
vcharlinecount <= 4'd15;
end
else
begin
if ( vcharlinecount==4'd8 )
begin
voffset <= voffset + 11'd53;
vcharlinecount <= 4'd15;
end
else
vcharlinecount <= vcharlinecount + 4'd1;
end
if ( vcount==VMAX )
begin
vcount <= 9'd0;
clr3 <= 3'b001;
end
else
vcount <= vcount + 9'd1;
if ( vcount==VTXTS_END )
vtxtscr <= 1'b0;
else if ( vcount==VTXTS_BEG )
vtxtscr <= 1'b1;
if ( vcount==VSYNC_BEG )
vsync <= 1'b1;
else if ( vcount==VSYNC_END )
vsync <= 1'b0;
if ( vcount==VBORD_BEG )
begin
vbord <= 1'b1;
vsetka <= 4'd5;
vchess <= 5'd0;
circle <= 1'b0;
bccount <= 7'd0;
sccount <= 5'd0;
bcdir <= 2'b00;
scdir <= 2'b00;
end
else
begin
if (bcdir[0])
bccount <= bccount+7'd1;
else if (bcdir[1])
bccount <= bccount-7'd1;
if (scdir[0])
sccount <= sccount+5'd1;
else if (scdir[1])
sccount <= sccount-5'd1;
if ( vsetka==4'd14 )
begin
vsetka <= 4'd0;
vchess <= vchess+5'd1;
end
else
begin
vsetka <= vsetka+4'd1;
if ( vsetka==4'd13 )
begin
if (vchess==5'd1)
bcdir <= 2'b01;
else if (vchess==5'd9)
bcdir <= 2'b10;
else if (vchess==5'd17)
bcdir <= 2'b00;
if ( (vchess==5'd0) || (vchess==5'd14) )
scdir <= 2'b01;
else if ( (vchess==5'd2) || (vchess==5'd16) )
scdir <= 2'b10;
else if ( (vchess==5'd4) || (vchess==5'd18) )
scdir <= 2'b00;
end
end
if ( vcount==VBORD_END ) vbord <= 1'b0;
end
vmouse <= vcount - scr_mouse_y;
end
//
if ( (hchess==5'd2) || (hchess==5'd10) || (hchess==5'd20) )
hhole <= 1'b1;
else if ( (hchess==5'd4) || (hchess==5'd14) || (hchess==5'd22) )
hhole <= 1'b0;
//
if ( (vchess==5'd4) && (schcnt==6'd63) )
begin
if (hchess==5'd7)
uhole <= 1'b1;
else if (hchess==5'd17)
uhole <= 1'b0;
end
//
if (hcount==(9'd258+cb_val))
circle <= 1'b0;
else if ( (schcnt==(5'd31+cs_val)) && (sccount!=5'd0) )
circle <= 1'b0;
else if (hcount==(9'd257-cb_val))
circle <= 1'b1;
else if ( (schcnt==(5'd30-cs_val)) && (sccount!=5'd0) )
circle <= 1'b1;
//
if ( (((vchess==5'd2) || (vchess==5'd16)) && (vsetka==4'd7)) || (vchess==5'd9) )
vhole <= 1'b1;
else if ( (((vchess==5'd3) || (vchess==5'd17)) && (vsetka==4'd7)) || (vchess==5'd11) )
vhole <= 1'b0;
//
end
circl_b ccb ( .in_addr(bccount), .out_word(cb_val) );
circl_s ccs ( .in_addr(sccount), .out_word(cs_val) );
lpm_rom_7x2 mouse_cursor ( .address({ vmouse[3:0], hmouse[2:0] }), .q({ mouse_i, mouse_m }) );
assign mouse_here = (hmouse[8:3] == 6'd0) && (vmouse[8:4] == 5'd0);
assign mouse_mask = mouse_here & mouse_m;
assign mouse_image = mouse_here & mouse_i;
assign video_addr = voffset + { 4'h0, hcharcount[5:0] };
lpm_ram_dp_9x8 scrmem0 ( .data(indata), .wraddress(scr_addr[8:0]), .wren((scr_wren_c)&&(scr_addr[10:9]==2'h0)),
.rdaddress(video_addr[8:0]), .q(charcode0) );
lpm_ram_dp_9x8 scrmem1 ( .data(indata), .wraddress(scr_addr[8:0]), .wren((scr_wren_c)&&(scr_addr[10:9]==2'h1)),
.rdaddress(video_addr[8:0]), .q(charcode1) );
lpm_ram_dp_9x8 scrmem2 ( .data(indata), .wraddress(scr_addr[8:0]), .wren((scr_wren_c)&&(scr_addr[10:9]==2'h2)),
.rdaddress(video_addr[8:0]), .q(charcode2) );
assign charcode = (video_addr[10:9]==2'h0) ? charcode0 :
(video_addr[10:9]==2'h1) ? charcode1 : charcode2 ;
lpm_ram_dp_9x8 attrmem0 ( .data(scr_attr), .wraddress(scr_addr[8:0]), .wren((scr_wren_a)&&(scr_addr[10:9]==2'h0)),
.rdaddress(video_addr[8:0]), .q(attrcode0) );
lpm_ram_dp_9x8 attrmem1 ( .data(scr_attr), .wraddress(scr_addr[8:0]), .wren((scr_wren_a)&&(scr_addr[10:9]==2'h1)),
.rdaddress(video_addr[8:0]), .q(attrcode1) );
lpm_ram_dp_9x8 attrmem2 ( .data(scr_attr), .wraddress(scr_addr[8:0]), .wren((scr_wren_a)&&(scr_addr[10:9]==2'h2)),
.rdaddress(video_addr[8:0]), .q(attrcode2) );
assign attrcode = (video_addr[10:9]==2'h0) ? attrcode0 :
(video_addr[10:9]==2'h1) ? attrcode1 : attrcode2 ;
assign vcharline = (vcharlinecount[3]) ? ~vcharlinecount[2:0] : vcharlinecount[2:0];
lpm_rom_11x6 chargen ( .address({ charcode, vcharline }), .q(charpix) );
assign fcolor = { attrcode[2], (attrcode[2]&attrcode[3]),
attrcode[1], (attrcode[1]&attrcode[3]),
attrcode[0], (attrcode[0]&attrcode[3]) };
assign bcolor = { (attrcode[6]&attrcode[7]), (attrcode[6]&(~attrcode[7])),
(attrcode[5]&attrcode[7]), (attrcode[5]&(~attrcode[7])),
(attrcode[4]&attrcode[7]), (attrcode[4]&(~attrcode[7])) };
assign fontenable = (charcode[7:4]==4'hb)||
(charcode[7:4]==4'hc)||
(charcode[7:4]==4'hd)||
(~vcharlinecount[3]);
assign pixel = ( charcode==8'hb0 ) ? ( (vcount[0]^hcount[1])&~hcount[0] ) :
( charcode==8'hb1 ) ? ( vcount[0]^hcount[0] ) :
( charcode==8'hb2 ) ? ( (vcount[0]^hcount[1])| hcount[0] ) :
( fontenable ) ? charpix[3'd5-pixptr] : 1'b0;
assign image_color = (mouse_mask) ? BLACK : ( pixel ? fcolor : bcolor ) ;
assign { vgrn[1:0], vred[1:0], vblu[1:0] } = color;
assign vhsync = hsync;
assign vvsync = vsync;
assign vcsync = ~csync;
//--AVRSPI--FlashROM-----------------------------------------------------------
localparam TEMP_REG = 8'ha0;
localparam SD_CS0 = 8'ha1;
localparam SD_CS1 = 8'ha2;
localparam FLASH_LOADDR = 8'ha3;
localparam FLASH_MIDADDR = 8'ha4;
localparam FLASH_HIADDR = 8'ha5;
localparam FLASH_DATA = 8'ha6;
localparam FLASH_CTRL = 8'ha7;
localparam SCR_LOADDR = 8'ha8;
localparam SCR_HIADDR = 8'ha9;
localparam SCR_SET_ATTR = 8'haa; // чряшё№ т ATTR
localparam SCR_FILL = 8'hab; // яЁхфшэъЁхьхэЄ рфЁхёр ш чряшё№ т ATTR ш т ярь Є№
// (хёыш Єюы№ъю фхЁурЄ№ spics_n, Єю т ярь Є№ сєфхЄ яшёрЄ№ё яЁхф√фє∙хх чэрўхэшх)
localparam SCR_CHAR = 8'hac; // яЁхфшэъЁхьхэЄ рфЁхёр ш чряшё№ т ярь Є№ ёшьтюыют ш ATTR т ярь Є№ рЄЁшсєЄют
// (хёыш Єюы№ъю фхЁурЄ№ spics_n, Єю т ярь Є№ сєфхЄ яшёрЄ№ё яЁхф√фє∙шх чэрўхэш )
localparam SCR_MOUSE_X = 8'had;
localparam SCR_MOUSE_Y = 8'hae;
localparam SCR_MODE = 8'haf; // [7] - 0=VGAmode, 1=TVmode; [2:0] - 0=TXT, шэрўх ScrTESTs
localparam MTST_CONTROL = 8'h50; // [0] - ЄхёЄ ярь Єш (0=ёсЁюё, 1=ЁрсюЄр)
localparam MTST_PASS_CNT0= 8'h51;
localparam MTST_PASS_CNT1= TEMP_REG;
localparam MTST_FAIL_CNT0= 8'h52;
localparam MTST_FAIL_CNT1= TEMP_REG;
localparam COVOX = 8'h53;
localparam INT_CONTROL = 8'h54; // [0] - ЁрчЁх°хэшх яЁхЁ√трэшщ юЄ covox-р (27343.75 Hz)
// [1] - ЁрчЁх°хэшх ърфЁют√ї яЁхЁ√трэшщ (~49 Hz)
reg [7:0] number; initial number = 8'hff;
reg [7:0] indata; initial indata = 8'hff;
reg [7:0] outdata;
reg [2:0] bitptr;
reg prev_spics_n;
reg [18:0] flash_addr;
reg flash_cs; initial flash_cs = 1'b0;
reg flash_oe; initial flash_oe = 1'b0;
reg flash_we; initial flash_we = 1'b0;
reg flash_postinc; initial flash_postinc = 1'b0;
reg [7:0] flash_data_out;
reg [10:0] scr_addr; initial scr_addr = 11'h000;
reg [7:0] scr_attr; initial scr_attr = 8'h0f;
reg scr_wren_c; initial scr_wren_c = 1'b0;
reg scr_wren_a; initial scr_wren_a = 1'b0;
reg [8:0] scr_mouse_x; initial scr_mouse_x = 9'd0;
reg [8:0] scr_mouse_y; initial scr_mouse_y = 9'd0;
reg scr_tv_mode; initial scr_tv_mode = 1'b1;
reg [2:0] scr_mode; initial scr_mode = 3'b0;
wire spicsn_rising;
wire spicsn_falling;
wire sd_selected;
reg cs_trg;
reg [7:0] temp_reg;
always @(posedge spick)
begin
if ( spics_n )
number <= { number[6:0], spido };
else
indata <= { indata[6:0], spido };
end
always @(negedge spick or posedge spics_n)
begin
if ( spics_n )
bitptr <= 3'b111;
else
bitptr <= bitptr - 3'b001;
end
always @(posedge fclk)
begin
//
if ( spicsn_rising )
begin
//
cs_trg <= 1'b1;
//
case ( number )
FLASH_LOADDR: flash_addr[7:0] <= indata;
FLASH_MIDADDR: flash_addr[15:8] <= indata;
FLASH_HIADDR: flash_addr[18:16] <= indata[2:0];
FLASH_DATA: begin
flash_data_out <= indata;
if (flash_postinc) flash_addr[13:0] <= flash_addr[13:0] + 14'd1;
end
FLASH_CTRL: begin
flash_cs <= indata[0];
flash_oe <= indata[1];
flash_we <= indata[2];
flash_postinc <= indata[3];
end
SCR_LOADDR: scr_addr[7:0] <= indata;
SCR_HIADDR: scr_addr[10:8] <= indata[2:0];
SCR_SET_ATTR: scr_attr <= indata;
SCR_FILL: begin
scr_attr <= indata;
scr_wren_a <= 1'b1;
end
SCR_CHAR: begin
scr_wren_c <= 1'b1;
scr_wren_a <= 1'b1;
end
TEMP_REG: temp_reg <= indata;
SCR_MOUSE_X: scr_mouse_x <= { temp_reg[0], indata };
SCR_MOUSE_Y: scr_mouse_y <= { temp_reg[0], indata };
SCR_MODE: begin
scr_tv_mode <= indata[7];
scr_mode <= indata[2:0];
end
MTST_CONTROL: mtst_run <= indata[0];
COVOX: begin
covox[cvx_ptr_iinc] <= indata;
cvx_ptr_in <= cvx_ptr_iinc;
end
INT_CONTROL: begin
enable_covox_int <= indata[0];
enable_frame_int <= indata[1];
end
endcase
//
end
else
begin
//
scr_wren_c <= 1'b0;
scr_wren_a <= 1'b0;
//
if ( spicsn_falling )
begin
//
cs_trg <= 1'b0;
//
case ( number )
SCR_SET_ATTR: outdata <= ~scr_attr; // for SPI testing
SCR_FILL: begin
outdata <= 8'hff;
scr_addr <= scr_addr + 11'd1;
end
SCR_CHAR: begin
outdata <= 8'hff;
scr_addr <= scr_addr + 11'd1;
end
FLASH_DATA: outdata <= d;
MTST_PASS_CNT0:begin
outdata <= mtst_pass_counter[7:0];
temp_reg <= mtst_pass_counter[15:8];
end
MTST_FAIL_CNT0:begin
outdata <= mtst_fail_counter[7:0];
temp_reg <= mtst_fail_counter[15:8];
end
COVOX: outdata <= { 4'd0, cvx_ptr_diff };
TEMP_REG: outdata <= temp_reg; // read after MTST_PASS_CNT0, MTST_FAIL_CNT0
default: outdata <= 8'hff;
endcase
//
end
//
end
//
prev_spics_n <= spics_n;
//
end
assign spicsn_rising = ( { cs_trg, prev_spics_n, spics_n } == 3'b011 );
assign spicsn_falling = ( { cs_trg, prev_spics_n, spics_n } == 3'b100 );
assign sd_selected = ( ( (number==SD_CS0) || (number==SD_CS1) ) && (~spics_n) );
assign spidi = sd_selected ? sddi : outdata[bitptr];
assign sddo = sd_selected ? spido : 1'b1;
assign sdclk = sd_selected ? spick : 1'b0;
assign sdcs_n = !( (number==SD_CS0) && (~spics_n) );
assign a[13:0] = flash_addr[13:0];
assign rompg0_n = ~flash_addr[14];
assign { rompg4, rompg3, rompg2, dos_n } = flash_addr[18:15];
assign csrom = flash_cs;
assign romoe_n = ~flash_oe;
assign romwe_n = ~flash_we;
assign d = flash_oe ? 8'bZZZZZZZZ : flash_data_out;
//-----------------------------------------------------------------------------
reg mtst_run; initial mtst_run = 1'b0;
wire [15:0] mtst_pass_counter;
wire [15:0] mtst_fail_counter;
mem_tester mtst( .clk(fclk), .rst_n(mtst_run),
.pass_counter(mtst_pass_counter),
.fail_counter(mtst_fail_counter),
.DRAM_DQ(rd), .DRAM_MA(ra), .DRAM_RAS0_N(rras0_n), .DRAM_RAS1_N(rras1_n),
.DRAM_LCAS_N(rlcas_n), .DRAM_UCAS_N(rucas_n), .DRAM_WE_N(rwe_n) );
//-----------------------------------------------------------------------------
endmodule