1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-27 20:58:30 +00:00

Some Work on King & Balloon

This commit is contained in:
Marcel
2019-08-18 12:19:00 +02:00
parent 82d956482c
commit 86e1134ddd
32 changed files with 4012 additions and 1244 deletions

View File

@@ -429,4 +429,5 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# end ENTITY(Laser310_MiST)
# -------------------------
set_global_assignment -name VERILOG_FILE rtl/fdc.v
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -47,7 +47,7 @@ input [7:0] key_code,
input [9:0] SWITCH,
input UART_RXD,
output UART_TXD
);
reg [3:0] CLK;
@@ -56,45 +56,38 @@ reg MEM_OP_WR;
(*keep*)reg GPIO_CPU_CLK;
// Processor
(*keep*)reg CPU_CLK;
(*keep*)wire [15:0] CPU_A;
(*keep*)wire [7:0] CPU_DI;
(*keep*)wire [7:0] CPU_DO;
(*keep*)wire[15:0] CPU_A;
(*keep*)wire [7:0] CPU_DI;
(*keep*)wire [7:0] CPU_DO;
(*keep*)wire CPU_RESET;
(*keep*)wire CPU_HALT;
(*keep*)wire CPU_MREQ;
(*keep*)wire CPU_RD;
(*keep*)wire CPU_WR;
(*keep*)wire CPU_IORQ;
(*keep*)reg CPU_INT;
(*keep*)wire CPU_M1;
wire CPU_BUSRQ;
wire CPU_BUSAK;
wire CPU_RFSH;
wire CPU_BUSRQ;
wire CPU_BUSAK;
wire CPU_RFSH;
(*keep*)wire CPU_RESET_N;
(*keep*)wire CPU_HALT_N;
(*keep*)wire CPU_MREQ_N;
(*keep*)wire CPU_RD_N;
(*keep*)wire CPU_WR_N;
(*keep*)wire CPU_IORQ_N;
(*keep*)wire CPU_INT_N;
(*keep*)wire CPU_M1_N;
wire CPU_BUSRQ_N;
wire CPU_BUSAK_N;
wire CPU_RFSH_N;
wire CPU_BUSRQ_N;
wire CPU_BUSAK_N;
wire CPU_RFSH_N;
// VRAM
(*keep*)wire [12:0] VRAM_ADDRESS;
(*keep*)wire[12:0] VRAM_ADDRESS;
(*keep*)wire VRAM_WR;
(*keep*)wire [7:0] VRAM_DATA_OUT;
(*keep*)wire [7:0] VRAM_DATA_OUT;
(*keep*)wire VDG_RD;
(*keep*)wire [12:0] VDG_ADDRESS;
(*keep*)wire [7:0] VDG_DATA;
(*keep*)wire[12:0] VDG_ADDRESS;
(*keep*)wire [7:0] VDG_DATA;
// ROM IO RAM
reg LATCHED_DOSROM_EN;
reg LATCHED_BOOTROM_EN;
@@ -1082,4 +1075,105 @@ assign CASS_OUT = EMU_CASS_EN ? EMU_CASS_DAT : {LATCHED_IO_DATA_WR[2], 1'b0};
(*keep*)wire trap = (CPU_RD|CPU_WR) && (CPU_A[15:12] == 4'h0);
assign AUD_ADCDAT = {LATCHED_IO_DATA_WR[0],LATCHED_IO_DATA_WR[5]};
// floppy
wire ADDRESS_IO_FDC;
wire ADDRESS_IO_FDC_CT;
wire ADDRESS_IO_FDC_DATA;
wire ADDRESS_IO_FDC_POLL;
wire ADDRESS_IO_FDC_WP;
reg [7:0] LATCHED_IO_FDC;
reg [7:0] LATCHED_IO_FDC_CT;
reg [7:0] LATCHED_RAM_DATA_FDC;
// floppy
(*keep*)wire FDC_RAM_R;
(*keep*)wire FDC_RAM_W;
(*keep*)wire [17:0] FDC_RAM_ADDR_R;
(*keep*)wire [17:0] FDC_RAM_ADDR_W;
reg [7:0] LAST_WRITE_DATA;
(*keep*)wire [7:0] FDC_RAM_DATA_W;
(*keep*)wire [7:0] FLOPPY_RD_DATA;
(*keep*)wire [7:0] FLOPPY_DATA;
// FDC
// if({CPU_IORQ,CPU_RD,CPU_WR,ADDRESS_IO_FDC_CT}==4'b1011)
// LATCHED_IO_FDC_CT <= CPU_DO;
// if({CPU_IORQ,CPU_RD,CPU_WR}==3'b110)
// LATCHED_IO_FDC <= ADDRESS_IO_FDC_POLL ? {FDC_POLL, 7'h7F} :
// ADDRESS_IO_FDC_DATA ? FDC_DATA :
// ADDRESS_IO_FDC_WP ? {FDC_WP, 7'h7F} :
// 8'hFF;
wire FLOPPY_WP_READ = 1'b0;
wire RAM_ADDRESS_FD_R = FDC_RAM_ADDR_R;
wire RAM_ADDRESS_FD_W = FDC_RAM_ADDR_W;
assign ADDRESS_IO_FDC = (CPU_A[7:2] == 6'b000100)?1'b1:1'b0;
assign ADDRESS_IO_FDC_CT = (CPU_A[7:0] == 8'h10)?1'b1:1'b0;
assign ADDRESS_IO_FDC_DATA = (CPU_A[7:0] == 8'h11)?1'b1:1'b0;
assign ADDRESS_IO_FDC_POLL = (CPU_A[7:0] == 8'h12)?1'b1:1'b0;
assign ADDRESS_IO_FDC_WP = (CPU_A[7:0] == 8'h13)?1'b1:1'b0;
wire [7:0] FDC_DATA;
wire FDC_POLL;
wire FDC_WP;
wire [7:0] SECTOR_BYTE;
wire [7:0] TRACK1_NO;
wire [7:0] TRACK2_NO;
wire DRIVE1;
wire DRIVE2;
wire MOTOR;
wire FDC_IO_R;
wire FDC_IO_W;
wire FDC_SIG;
wire FDC_SIG_CLK;
wire FDC_IO = (CPU_IORQ&ADDRESS_IO_FDC);
wire FDC_IO_POLL = (CPU_IORQ&ADDRESS_IO_FDC_POLL);
wire FDC_IO_DATA = (CPU_IORQ&ADDRESS_IO_FDC_DATA);
wire FDC_IO_CT = (CPU_IORQ&ADDRESS_IO_FDC_CT);
FDC_IF FDC_U (
.FDC_CLK(CPU_CLK),
.RESET_N(RESET_N),
.SW(SWITCH[3:2]),
.DBG(SWITCH[9:6]),
.FDC_RAM_R(FDC_RAM_R),
.FDC_RAM_W(FDC_RAM_W),
.FDC_RAM_ADDR_R(FDC_RAM_ADDR_R),
.FDC_RAM_ADDR_W(FDC_RAM_ADDR_W),
.FDC_RAM_DATA_R(LATCHED_RAM_DATA_FDC),
.FDC_RAM_DATA_W(FDC_RAM_DATA_W),
.FDC_IO(FDC_IO),
.FDC_IO_POLL(FDC_IO_POLL),
.FDC_IO_DATA(FDC_IO_DATA),
.FDC_IO_CT(FDC_IO_CT),
.FDC_SIG(FDC_SIG),
.FDC_SIG_CLK(FDC_SIG_CLK),
.FDC_CT(LATCHED_IO_FDC_CT),
.FDC_DATA(FDC_DATA),
.FDC_POLL(FDC_POLL),
.FDC_WP(FDC_WP),
.FLOPPY_SECTOR_BYTE(SECTOR_BYTE),
.TRACK1_NO(TRACK1_NO),
.TRACK2_NO(TRACK2_NO),
.DRIVE1(DRIVE1),
.DRIVE2(DRIVE2),
.MOTOR(MOTOR)
);
endmodule

View File

@@ -96,7 +96,7 @@ mist_video #(.COLOR_DEPTH(6)) mist_video(
.VGA_B(VGA_B),
.VGA_VS(VGA_VS),
.VGA_HS(VGA_HS),
.scandoubler_disable(scandoublerD),
.scandoubler_disable(1'b1),//scandoublerD),
.scanlines(status[4:3]),
.ypbpr(ypbpr)
);

View File

@@ -0,0 +1,967 @@
/*****************************************************************************
* Floppy
******************************************************************************/
// POLLING after Clock
// vz dsk Parameter
// 154 * 16 * 40 = 98560 = 0x18100
// 154 * 16 = 2464 = 0x9A0 = 0x4D0 * 2
`define FD_MAX_LEN 17'h18100
`define FD_TRACK_LEN 12'h9A0
`define FD_TRACK_STEP 8'h4D
// 40*2 0 --- 78
`define FD_MAX_TRACK_NO 8'd78
module FDC_IF (
FDC_CLK,
RESET_N,
SW,
DBG,
FDC_RAM_R,
FDC_RAM_W,
FDC_RAM_ADDR_R,
FDC_RAM_ADDR_W,
FDC_RAM_DATA_R,
FDC_RAM_DATA_W,
FDC_IO,
FDC_IO_POLL,
FDC_IO_DATA,
FDC_IO_CT,
FDC_SIG,
FDC_SIG_CLK,
FDC_CT,
FDC_DATA,
FDC_POLL,
FDC_WP,
FLOPPY_SECTOR_BYTE,
TRACK1_NO,
TRACK2_NO,
DRIVE1,
DRIVE2,
MOTOR
);
input FDC_CLK;
input RESET_N;
input [1:0] SW;
input [3:0] DBG;
output [17:0] FDC_RAM_ADDR_R;
output [17:0] FDC_RAM_ADDR_W;
output reg FDC_RAM_R;
output reg FDC_RAM_W;
input [7:0] FDC_RAM_DATA_R;
output [7:0] FDC_RAM_DATA_W;
input FDC_IO;
input FDC_IO_POLL;
input FDC_IO_DATA;
input FDC_IO_CT;
output FDC_SIG;
output reg FDC_SIG_CLK;
input [7:0] FDC_CT;
output [7:0] FDC_DATA;
output FDC_POLL;
output FDC_WP;
reg [11:0] FLOPPY_BYTE;
output reg [7:0] FLOPPY_SECTOR_BYTE; // Count Sector Bytes
reg [6:0] CLK_CNT;
reg [6:0] CLK_CNT_W;
reg [18:0] SYNC_CNT;
reg [7:0] FLOPPY_SECTOR_DELAY; // Delay on Sector End
reg FD_REC1;
reg FDC_POLL1;
reg FDC_REC_DATA_BIT1;
reg FDC_DATA_BIT1;
reg [7:0] FDC_DATA1;
reg [7:0] LATCHED_FDC_DATA1;
reg FDC_DATA_SET1;
reg FD_REC2;
reg FDC_POLL2;
reg FDC_REC_DATA_BIT2;
reg FDC_DATA_BIT2;
reg [7:0] FDC_DATA2;
reg [7:0] LATCHED_FDC_DATA2;
reg [3:0] BIT_CNT_W;
reg [2:0] BIT_CNT;
wire FDC_RAM_DATA_R_BIT;
reg [1:0] STEPPER1;
reg [1:0] STEPPER2;
output reg [7:0] TRACK1_NO;
output reg [7:0] TRACK2_NO;
reg [12:0] TRACK1;
reg [12:0] TRACK2;
(*keep*)wire [13:0] TRACK;
wire [12:0] TRACK1_UP;
wire [12:0] TRACK1_DOWN;
wire [12:0] TRACK2_UP;
wire [12:0] TRACK2_DOWN;
reg [17:0] FLOPPY_ADDRESS_R;
reg [17:0] FLOPPY_ADDRESS_W;
//reg [7:0] FLOPPY_WRITE_DATA;
reg WRITE_WAIT_FIRST_OP;
reg WRITE_DATA_BIT_VAL;
reg [7:0] WRITE_DATA1;
reg WRITE_DATA_MODI1;
reg [7:0] WRITE_DATA2;
reg WRITE_DATA2_MODI;
(*keep*)wire [7:0] FLOPPY_RD_DATA;
(*keep*)wire [7:0] FLOPPY_DATA;
(*keep*)wire FLOPPY_READ;
(*keep*)wire FLOPPY_WRITE;
wire FLOPPY_WP_READ;
reg PHASE0;
reg PHASE0_1;
reg PHASE0_2;
reg PHASE1;
reg PHASE1_1;
reg PHASE1_2;
reg PHASE2;
reg PHASE2_1;
reg PHASE2_2;
reg PHASE3;
reg PHASE3_1;
reg PHASE3_2;
output reg DRIVE1;
output reg DRIVE2;
output reg MOTOR;
reg WRITE_REQUEST_N;
reg WRITE_DATA_BIT;
reg Q6;
reg Q7;
wire DRIVE1_EN;
wire DRIVE2_EN;
wire DRIVE1_X;
wire DRIVE2_X;
wire DRIVE_SWAP;
wire DRIVE1_FLOPPY_WP;
wire DRIVE2_FLOPPY_WP;
reg MODIFY_DRIVE1;
reg MODIFY_DRIVE2;
assign FDC_RAM_ADDR_R = FLOPPY_ADDRESS_R;
assign FDC_RAM_ADDR_W = FLOPPY_ADDRESS_W;
(*preserve*)reg [7:0] FDC_CNT;
(*preserve*)reg [7:0] FDC_CNT_POLL;
(*preserve*)reg [7:0] FDC_CNT_DATA;
(*preserve*)reg [19:0] FDC_CNT_CT;
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
FDC_CNT <= 8'hFF;
FDC_CNT_POLL <= 8'hFF;
FDC_CNT_DATA <= 8'hFF;
FDC_CNT_CT <= 20'hFFFFF;
end
else
begin
if(FDC_IO)
FDC_CNT <= 0;
else if(~FDC_CNT[7])
FDC_CNT <= FDC_CNT + 1;
if(FDC_IO_POLL)
FDC_CNT_POLL <= 0;
else if(~FDC_CNT_POLL[7])
FDC_CNT_POLL <= FDC_CNT_POLL + 1;
if(FDC_IO_DATA)
FDC_CNT_DATA <= 0;
else if(~FDC_CNT_DATA[7])
FDC_CNT_DATA <= FDC_CNT_DATA + 1;
if(FDC_IO_CT)
FDC_CNT_CT <= 0;
else if(~FDC_CNT_CT[19])
FDC_CNT_CT <= FDC_CNT_CT + 1;
end
end
assign FDC_POLL = (DRIVE1_EN)?FDC_POLL1:
(DRIVE2_EN)?FDC_POLL2:
1'b0;
assign FDC_DATA = (DRIVE1_EN)?FDC_DATA1:
(DRIVE2_EN)?FDC_DATA2:
8'hFF;
assign FDC_RAM_DATA_R_BIT = (BIT_CNT==3'd7)?FDC_RAM_DATA_R[7]:
(BIT_CNT==3'd6)?FDC_RAM_DATA_R[6]:
(BIT_CNT==3'd5)?FDC_RAM_DATA_R[5]:
(BIT_CNT==3'd4)?FDC_RAM_DATA_R[4]:
(BIT_CNT==3'd3)?FDC_RAM_DATA_R[3]:
(BIT_CNT==3'd2)?FDC_RAM_DATA_R[2]:
(BIT_CNT==3'd1)?FDC_RAM_DATA_R[1]:
FDC_RAM_DATA_R[0];
// 读取
reg LATCHED_FD_REC1;
reg LATCHED_FDC_IO_DATA1;
reg GET_FDC_POLLING;
reg [5:0] FDC_POLL1_CNT;
reg [5:0] GET_FDC_POLL1_CNT;
always @(posedge FDC_CLK or negedge RESET_N)
if(~RESET_N)
begin
FDC_DATA_BIT1 <= 1'b0;
LATCHED_FD_REC1 <= 1'b0;
LATCHED_FDC_IO_DATA1 <= 1'b0;
end
else
begin
// 磁道记录信号上沿翻转 DATA_BIT
if({LATCHED_FD_REC1, FD_REC1}==2'b01)
begin
FDC_DATA_BIT1 <= FDC_POLL1;
end
if(FDC_DATA_SET1)
LATCHED_FDC_DATA1 <= {LATCHED_FDC_DATA1[6:0], FDC_DATA_BIT1};
// 读取DATA信号上沿
if({LATCHED_FDC_IO_DATA1, FDC_IO_DATA}==2'b01)
begin
FDC_DATA1 <= LATCHED_FDC_DATA1;
end
LATCHED_FD_REC1 <= FD_REC1;
LATCHED_FDC_IO_DATA1 <= FDC_IO_DATA;
end
////////////////////////////////////////
// 物理软驱模拟
////////////////////////////////////////
//WRITE_REQUEST_N
(*preserve*)reg [9:0] WRITE_DATA_CNT;
assign FDC_RAM_DATA_W = WRITE_DATA1;
// 对写入操作计数
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
WRITE_DATA_CNT <= 0;
end
else
begin
if( (~FDC_CT[6]) && (FDC_CT[5]==LATCHED_FDC_CT[5]) )
begin
if(~WRITE_DATA_CNT[9])
WRITE_DATA_CNT <= WRITE_DATA_CNT+1;
end
else
begin
WRITE_DATA_CNT <= 0;
end
end
end
// 模拟磁道信号
// 等待第1个写入数据变化
always @(posedge FDC_CLK or negedge RESET_N)
if(~RESET_N)
begin
WRITE_WAIT_FIRST_OP <= 1'b0;
end
else
begin
if( LATCHED_FDC_CT[6]!=FDC_CT[6] )
begin
// 信号下拉开始写入并等待第1个写入数据变化
WRITE_WAIT_FIRST_OP <= ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b10);
end
else
begin
// 找到第1个写入数据变化
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && (FDC_CT[5]!=LATCHED_FDC_CT[5]) )
WRITE_WAIT_FIRST_OP <= 1'b0;
end
end
// 判断是否有写入数据产生
always @(posedge FDC_CLK or negedge RESET_N)
if(~RESET_N)
begin
WRITE_DATA_MODI1 <= 1'b0;
end
else
begin
// 写入信号变化
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && (FDC_CT[5]!=LATCHED_FDC_CT[5]) )
begin
WRITE_DATA_MODI1 <= 1'b1;
end
else
begin
if(FDC_RAM_W)
WRITE_DATA_MODI1 <= 1'b0;
end
end
// 判断写入的值
always @(posedge FDC_CLK or negedge RESET_N)
if(~RESET_N)
begin
WRITE_DATA_BIT_VAL <= 1'b0;
end
else
begin
// 写入信号变化
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && (FDC_CT[5]!=LATCHED_FDC_CT[5]) )
begin
// 9'h01B 9'h056 9'h072
if(WRITE_DATA_CNT==10'h01B)
begin
WRITE_DATA_BIT_VAL <= 1'b1;
end
else
begin
WRITE_DATA_BIT_VAL <= 1'b0;
end
end
end
// 模拟磁盘数据位
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
SYNC_CNT <= 19'b0;
BIT_CNT <= 3'd0;
FDC_RAM_R <= 1'b0;
FDC_RAM_W <= 1'b0;
FDC_DATA_SET1 <= 1'b0;
FDC_POLL1 <= 1'b0;
FDC_POLL2 <= 1'b0;
FLOPPY_BYTE <= 12'h000;
FLOPPY_SECTOR_BYTE <= 8'h00;
FLOPPY_SECTOR_DELAY <= 8'h00;
FLOPPY_ADDRESS_R <= 18'b0;
FLOPPY_ADDRESS_W <= 18'b0;
WRITE_DATA1 <= 8'b0;
FD_REC1 <= 1'b0;
CLK_CNT <= 7'h00;
end
else
begin
begin
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && (FDC_CT[5]!=LATCHED_FDC_CT[5]) && WRITE_DATA_CNT[9] )
begin
// INIT 磁道空白区约1/10圈空白
// 找到第1个时钟位
BIT_CNT <= 3'd7;
// 下一个需要读取的位置
FLOPPY_BYTE <= 12'h001;
FLOPPY_SECTOR_BYTE <= 8'h00;
FLOPPY_ADDRESS_R <= {TRACK, 4'b0};
SYNC_CNT <= 19'b0;
FDC_RAM_R <= 1'b1;
FDC_RAM_W <= 1'b0;
FDC_DATA_SET1 <= 1'b0;
FD_REC1 <= 1'b1;
FDC_POLL1 <= 1'b0;
FDC_POLL2 <= 1'b0;
CLK_CNT <= 7'h03;
end
else
begin
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && (FDC_CT[5]!=LATCHED_FDC_CT[5]) && WRITE_DATA_CNT==10'h02F )
begin
// 格式化时数据区之前无空白数据存盘时写入数据区留有50个左右的时钟周期空白
// 写入扇区定位写入扇区前有约0x28个时钟周期的空白
FDC_RAM_W <= 1'b0;
FDC_DATA_SET1 <= 1'b0;
FD_REC1 <= 1'b1;
FDC_POLL1 <= 1'b0;
FDC_POLL2 <= 1'b0;
CLK_CNT <= 7'h03;
end
else
begin
case(CLK_CNT)
7'h00: // 同步信号 324 * 8 * 0x70 = 290304
begin
FD_REC1 <= 1'b0;
SYNC_CNT <= SYNC_CNT+1;
FDC_RAM_R <= 1'b0;
FDC_RAM_W <= 1'b0;
if(SYNC_CNT[18])
//if(SYNC_CNT[10])
begin
CLK_CNT <= CLK_CNT + 1;
end
end
7'h01:
begin
FDC_RAM_R <= 1'b0;
FDC_RAM_W <= 1'b0;
// 如果是写入等待时钟沿的变化
if( ({LATCHED_FDC_CT[6],FDC_CT[6]}==2'b00) && ({LATCHED_FDC_CT[5],FDC_CT[5]}==2'b01) )
begin
CLK_CNT <= CLK_CNT;
end
else
begin
CLK_CNT <= CLK_CNT + 1;
end
end
// CLOCK DOMAIN
7'h02:
begin
BIT_CNT <= BIT_CNT-1;
// 读取
if(BIT_CNT==3'd0)
begin
begin
FLOPPY_BYTE <= FLOPPY_BYTE + 1'b1;
FLOPPY_ADDRESS_R <= {TRACK, 4'b0} + {6'b000000, FLOPPY_BYTE};
end
FDC_RAM_R <= 1'b1;
end
FD_REC1 <= 1'b1;
CLK_CNT <= CLK_CNT + 1;
end
// POOLING
// 从读取POLLING成功值为1到读取DATA中间间隔了0x43 个时钟周期
7'h03:
begin
FDC_RAM_R <= 1'b0;
FDC_RAM_W <= 1'b0;
FDC_POLL1 <= 1'b1;
FDC_POLL2 <= 1'b1;
CLK_CNT <= CLK_CNT + 1;
end
7'h06: // 1us
begin
FD_REC1 <= 1'b0;
CLK_CNT <= CLK_CNT + 1;
end
// DATA DOMAIN
7'h1E:
begin
FD_REC1 <= FDC_RAM_DATA_R_BIT;
CLK_CNT <= CLK_CNT + 1;
end
7'h1F:
begin
FDC_DATA_SET1 <= 1'b1;
CLK_CNT <= CLK_CNT + 1;
end
7'h20:
begin
FDC_DATA_SET1 <= 1'b0;
CLK_CNT <= CLK_CNT + 1;
end
7'h22:
begin
FD_REC1 <= 1'b0;
CLK_CNT <= CLK_CNT + 1;
end
7'h25:
begin
FDC_POLL1 <= 1'b0;
FDC_POLL2 <= 1'b0;
CLK_CNT <= CLK_CNT + 1;
end
// 扇区结束延时
7'h70:
begin
// 写入
WRITE_DATA1 <= {WRITE_DATA1[6:0],WRITE_DATA_BIT_VAL};
if(BIT_CNT==3'd0)
begin
FLOPPY_ADDRESS_W <= FLOPPY_ADDRESS_R;
FDC_RAM_W <= WRITE_DATA_MODI1;
end
CLK_CNT <= CLK_CNT + 1;
end
7'h71:
begin
// 写入结束
FDC_RAM_W <= 1'b0;
FDC_SIG_CLK <= WRITE_DATA_MODI1;
// 扇区结束时的延时
if(BIT_CNT==3'd0 && FLOPPY_SECTOR_BYTE==8'h99)
begin
FLOPPY_SECTOR_DELAY <= 8'hA5;
end
else
begin
FLOPPY_SECTOR_DELAY <= 8'h00;
end
CLK_CNT <= CLK_CNT + 1;
end
// 扇区结束时的延时
7'h72:
begin
FDC_SIG_CLK <= 1'b0;
// 扇区结束时的延时
if(FLOPPY_SECTOR_DELAY==8'h00)
begin
CLK_CNT <= CLK_CNT + 1;
end
else
begin
FLOPPY_SECTOR_DELAY <= FLOPPY_SECTOR_DELAY-1;
end
end
7'h73:
begin
if(BIT_CNT==3'd0)
begin
if(FLOPPY_BYTE==`FD_TRACK_LEN||FLOPPY_SECTOR_BYTE==8'h99)
begin
FLOPPY_SECTOR_BYTE <= 8'h00;
end
else
begin
FLOPPY_SECTOR_BYTE <= FLOPPY_SECTOR_BYTE+1;
end
end
if(BIT_CNT==3'd0 && FLOPPY_BYTE==`FD_TRACK_LEN)
begin
FLOPPY_BYTE <= 12'h000;
//FLOPPY_SECTOR_BYTE <= 8'h00;
FLOPPY_ADDRESS_R <= {TRACK, 4'b0};
SYNC_CNT <= 19'b0;
CLK_CNT <= 7'h00;
end
else
begin
CLK_CNT <= 7'h01;
end
end
default:
begin
FDC_RAM_R <= 1'b0;
FDC_RAM_W <= 1'b0;
CLK_CNT <= CLK_CNT + 1;
end
endcase
end
end
end
end
end
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
PHASE0 <= 1'b0;
PHASE1 <= 1'b0;
PHASE2 <= 1'b0;
PHASE3 <= 1'b0;
MOTOR <= 1'b0;
DRIVE1 <= 1'b0;
DRIVE2 <= 1'b0;
WRITE_REQUEST_N <= 1'b1;
WRITE_DATA_BIT <= 1'b0;
end
else
begin
PHASE0 <= FDC_CT[0];
PHASE1 <= FDC_CT[1];
PHASE2 <= FDC_CT[2];
PHASE3 <= FDC_CT[3];
DRIVE1 <= FDC_CT[4];
DRIVE2 <= FDC_CT[7];
MOTOR <= (FDC_CT[4])|(FDC_CT[7]);
WRITE_REQUEST_N <= FDC_CT[6];
WRITE_DATA_BIT <= FDC_CT[5];
end
end
//assign DRIVE1_X = DRIVE1 & MOTOR;
//assign DRIVE2_X = !DRIVE1 & MOTOR;
assign DRIVE1_X = DRIVE1 & MOTOR;
assign DRIVE2_X = DRIVE2 & MOTOR;
assign DRIVE1_FLOPPY_WP = ~SW[0];
assign DRIVE2_FLOPPY_WP = ~SW[1];
assign FDC_WP = DRIVE1?DRIVE1_FLOPPY_WP:
DRIVE2?DRIVE2_FLOPPY_WP:
1'b1;
assign DRIVE1_EN = (DRIVE1) & MOTOR;
assign DRIVE2_EN = (DRIVE2) & MOTOR;
assign TRACK = (DRIVE1_EN) ? {1'b0,TRACK1}:
(DRIVE2_EN) ? {1'b1,TRACK2}:
14'b0;
assign TRACK1_UP = TRACK1 + `FD_TRACK_STEP;
assign TRACK1_DOWN = TRACK1 - `FD_TRACK_STEP;
assign TRACK2_UP = TRACK2 + `FD_TRACK_STEP;
assign TRACK2_DOWN = TRACK2 - `FD_TRACK_STEP;
//assign FLOPPY_ADDRESS_R = {TRACK, 4'b0} + {5'b00000, FLOPPY_BYTE};
//always @ (posedge PH_2)
always @(negedge FDC_CLK)
begin
PHASE0_1 <= PHASE0;
PHASE0_2 <= PHASE0_1; // Delay 2 clock cycles
PHASE1_1 <= PHASE1;
PHASE1_2 <= PHASE1_1; // Delay 2 clock cycles
PHASE2_1 <= PHASE2;
PHASE2_2 <= PHASE2_1; // Delay 2 clock cycles
PHASE3_1 <= PHASE3;
PHASE3_2 <= PHASE3_1; // Delay 2 clock cycles
end
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
STEPPER1 <= 2'b00;
STEPPER2 <= 2'b00;
TRACK1 <= 13'd0;
TRACK2 <= 13'd0;
TRACK1_NO <= 8'd0;
TRACK2_NO <= 8'd0;
end
else
begin
// if(DRIVE1^DRIVE_SWAP)
if(DRIVE1)
begin
case ({PHASE0_2, PHASE1_2, PHASE2_2, PHASE3_2})
4'b1000:
begin
if(STEPPER1 == 2'b11)
begin
//if(TRACK1 != `FD_MAX_LEN)
if(TRACK1_NO != `FD_MAX_TRACK_NO)
begin
TRACK1 <= TRACK1_UP;
TRACK1_NO <= TRACK1_NO+1;
STEPPER1 <= 2'b00;
end
end
else
if(STEPPER1 == 2'b01)
begin
//if(TRACK1 != 17'h0)
if(TRACK1_NO != 8'd0)
begin
TRACK1 <= TRACK1_DOWN;
TRACK1_NO <= TRACK1_NO-1;
STEPPER1 <= 2'b00;
end
end
end
4'b0100:
begin
if(STEPPER1 == 2'b00)
begin
//if(TRACK1 != `FD_MAX_LEN)
if(TRACK1_NO != `FD_MAX_TRACK_NO)
begin
TRACK1 <= TRACK1_UP;
TRACK1_NO <= TRACK1_NO+1;
STEPPER1 <= 2'b01;
end
end
else
if(STEPPER1 == 2'b10)
begin
//if(TRACK1 != 17'h0)
if(TRACK1_NO != 8'd0)
begin
TRACK1 <= TRACK1_DOWN;
TRACK1_NO <= TRACK1_NO-1;
STEPPER1 <= 2'b01;
end
end
end
4'b0010:
begin
if(STEPPER1 == 2'b01)
begin
//if(TRACK1 != `FD_MAX_LEN)
if(TRACK1_NO != `FD_MAX_TRACK_NO)
begin
TRACK1 <= TRACK1_UP;
TRACK1_NO <= TRACK1_NO+1;
STEPPER1 <= 2'b10;
end
end
else
if(STEPPER1 == 2'b11)
begin
//if(TRACK1 != 17'h0)
if(TRACK1_NO != 8'd0)
begin
TRACK1 <= TRACK1_DOWN;
TRACK1_NO <= TRACK1_NO-1;
STEPPER1 <= 2'b10;
end
end
end
4'b0001:
begin
if(STEPPER1 == 2'b10)
begin
//if(TRACK1 != `FD_MAX_LEN)
if(TRACK1_NO != `FD_MAX_TRACK_NO)
begin
TRACK1 <= TRACK1_UP;
TRACK1_NO <= TRACK1_NO+1;
STEPPER1 <= 2'b11;
end
end
else
if(STEPPER1 == 2'b00)
begin
//if(TRACK1 != 17'h0)
if(TRACK1_NO != 8'd0)
begin
TRACK1 <= TRACK1_DOWN;
TRACK1_NO <= TRACK1_NO-1;
STEPPER1 <= 2'b11;
end
end
end
endcase
end
else
begin
case ({PHASE0_2, PHASE1_2, PHASE2_2, PHASE3_2})
4'b1000:
begin
if(STEPPER2 == 2'b11)
begin
//if(TRACK2 != `FD_MAX_LEN)
if(TRACK2_NO != `FD_MAX_TRACK_NO)
begin
TRACK2 <= TRACK2_UP;
TRACK2_NO <= TRACK2_NO+1;
STEPPER2 <= 2'b00;
end
end
else
if(STEPPER2 == 2'b01)
begin
//if(TRACK2 != 17'h0)
if(TRACK2_NO != 8'd0)
begin
TRACK2 <= TRACK2_DOWN;
TRACK2_NO <= TRACK2_NO-1;
STEPPER2 <= 2'b00;
end
end
end
4'b0100:
begin
if(STEPPER2 == 2'b00)
begin
//if(TRACK2 != `FD_MAX_LEN)
if(TRACK2_NO != `FD_MAX_TRACK_NO)
begin
TRACK2 <= TRACK2_UP;
TRACK2_NO <= TRACK2_NO+1;
STEPPER2 <= 2'b01;
end
end
else
if(STEPPER2 == 2'b10)
begin
//if(TRACK2 != 17'h0)
if(TRACK2_NO != 8'd0)
begin
TRACK2 <= TRACK2_DOWN;
TRACK2_NO <= TRACK2_NO-1;
STEPPER2 <= 2'b01;
end
end
end
4'b0010:
begin
if(STEPPER2 == 2'b01)
begin
//if(TRACK2 != `FD_MAX_LEN)
if(TRACK2_NO != `FD_MAX_TRACK_NO)
begin
TRACK2 <= TRACK2_UP;
TRACK2_NO <= TRACK2_NO+1;
STEPPER2 <= 2'b10;
end
end
else
if(STEPPER2 == 2'b11)
begin
//if(TRACK2 != 17'h0)
if(TRACK2_NO != 8'd0)
begin
TRACK2 <= TRACK2_DOWN;
TRACK2_NO <= TRACK2_NO-1;
STEPPER2 <= 2'b10;
end
end
end
4'b0001:
begin
if(STEPPER2 == 2'b10)
begin
//if(TRACK2 != `FD_MAX_LEN)
if(TRACK2_NO != `FD_MAX_TRACK_NO)
begin
TRACK2 <= TRACK2_UP;
TRACK2_NO <= TRACK2_NO+1;
STEPPER2 <= 2'b11;
end
end
else
if(STEPPER2 == 2'b00)
begin
//if(TRACK2 != 17'h0)
if(TRACK2_NO != 8'd0)
begin
TRACK2 <= TRACK2_DOWN;
TRACK2_NO <= TRACK2_NO-1;
STEPPER2 <= 2'b11;
end
end
end
endcase
end
end
end
reg [19:0] LATCHED_FDC_CNT_CT;
reg [7:0] LATCHED_FDC_CT;
always @(posedge FDC_CLK or negedge RESET_N)
begin
if(~RESET_N)
begin
LATCHED_FDC_CT <= 8'hFF;
//FDC_SIG_CLK <= 1'b0;
LATCHED_FDC_CNT_CT <= 20'hFFFFF;
end
else
begin
LATCHED_FDC_CT <= FDC_CT;
LATCHED_FDC_CNT_CT <= FDC_CNT_CT;
//FDC_SIG_CLK <= (LATCHED_FDC_CT!=FDC_CT);
end
end
assign FDC_SIG = (FDC_CNT[7]|FDC_CNT_POLL[7]|FDC_CNT_DATA[7]|FDC_CNT_CT[19]|(LATCHED_FDC_CNT_CT==0));
endmodule