📄 floppy.v
字号:
track[7:1]<=track[7:1]+{direc,direc,direc,direc,direc,direc,1'b1};//_dsktrack0 and dsktrack79 detectassign _dsktrack0=(track[7:1]==7'b0000000)?0:1;assign _dsktrack79=(track[7:1]==7'b1001111)?0:1;//motor (ready) controlalways @(posedge clk) if(reset)//reset _dskready<=1; else if(!_sel && _seld)//latch _motor signal at falling edge of _sel _dskready<=_motor;//--------------------------------------------------------------------------------------//disk data byte and status readassign dskbytr=(regaddress[8:1]==DSKBYTR[8:1])?{1'b0,(trackrd|trackwr),dsklen[14],13'b000000000000}:16'h0000; //disk sync registeralways @(posedge clk) if (reset) dsksync[15:0] <= 0; else if (regaddress[8:1]==DSKSYNC[8:1]) dsksync[15:0] <= datain[15:0];//disk length registeralways @(posedge clk) if (reset) dsklen[14:0] <= 0; else if (regaddress[8:1]==DSKLEN[8:1]) dsklen[14:0] <= datain[14:0]; else if (bufwr)//decrement length register dsklen[13:0] <= dsklen[13:0] - 1;//disk length register DMAENalways @(posedge clk) if (reset) dsklen[15] <= 0; else if (blckint) dsklen[15] <= 0; else if (regaddress[8:1]==DSKLEN[8:1]) dsklen[15] <= datain[15]; //dmaen - disk dma enable signalalways @(posedge clk) if (reset) dmaen <= 0; else if (blckint) dmaen <= 0; else if (regaddress[8:1]==DSKLEN[8:1]) dmaen <= datain[15] & dsklen[15];//start disk dma if second write in a row with dsklen[15] set//dsklen zero detectassign lenzero = (dsklen[13:0]==0) ? 1 : 0;//--------------------------------------------------------------------------------------//disk data read pathwire busrd; //bus readwire buswr; //bus writereg trackrdok; //track read enable//disk buffer bus read address decodeassign busrd=(regaddress[8:1]==DSKDATR[8:1])?1:0;//disk buffer bus write address decodeassign buswr=(regaddress[8:1]==DSKDAT[8:1])?1:0;//fifo data input multiplexerassign bufdin[15:0] = trackrd ? rx_data[15:0] : datain[15:0];//fifo write controlassign bufwr = (trackrdok & spidat & ~lenzero) | (buswr & dmaon);//delayed version to allow writing of the last word to empty fifoalways @(posedge clk) bufwr_del <= bufwr;//fifo read controlassign bufrd = (busrd & dmaon) | (trackwr & spidat);//DSKSYNC interrupt//assign syncint = dsksync[15:0]==rx_data[15:0] && spidat && trackrd ? 1 : 0;assign syncint = 16'h4489==rx_data[15:0] && spidat && trackrd ? 1 : 0;//track read enable / wait for syncword logicalways @(posedge clk) if (!trackrd)//reset trackrdok <= 0; else//wordsync is enabled, wait with reading untill syncword is found trackrdok <= ~wordsync | syncint | trackrdok;assign fifo_reset = reset | ~dmaen; //disk fifo / trackbufferfifo db1( .clk(clk), .reset(fifo_reset), .din(bufdin), .dout(bufdout), .rd(bufrd), .wr(bufwr), .full(buffull), .cnt(fifo_cnt), .empty(bufempty));//disk data read output gateassign dskdatr[15:0]=(busrd)?bufdout[15:0]:16'h0000;//--------------------------------------------------------------------------------------//dma request logicalways @(dmaon or dsklen or bufempty or buffull or horbeam) if(dmaon && (horbeam[8:4]==5'b00000) && (horbeam[1:0]==2'b11))//valid memory cycle and dma enabled begin if(!dsklen[14] && !bufempty)//dma write cycle (disk->ram) begin dmal=1; dmas=0; end else if(dsklen[14] && !buffull)//dma read cycle (ram->disk) begin dmal=1; dmas=1; end else begin dmal=0;//no track read or write action dmas=0; end end else begin dmal=0;//no valid memory cycle dmas=0; end//--------------------------------------------------------------------------------------//main disk controllerreg [1:0]dskstate; //current state of diskreg [1:0]nextstate; //next state of state//disk statesparameter DISKCHANGE=2'b00;parameter DISKPRESENT=2'b01;parameter DISKDMA=2'b10;parameter DISKINT=2'b11;//disk write protect statusalways @(posedge clk) if(reset) _dskwprot <= 0; else if (dskstate==DISKPRESENT && rx_flag && spi_cmd2) //PIC response to CMD_GETDSKSTAT _dskwprot <= rx_data[1];//main disk state machinealways @(posedge clk) if(reset) dskstate<=DISKCHANGE; else dskstate<=nextstate; always @(dskstate or spidat or rx_data or dmaen or lenzero or enable or dsklen or bufempty or rx_flag or spi_cmd2 or bufwr_del)// or _sden)begin case(dskstate) DISKCHANGE://disk is removed from flash drive, poll drive for new disk begin trackrd=0; trackwr=0; trackch=1; dmaon=0; blckint=0; _dskchange=0; if(rx_flag && spi_cmd2 && rx_data[0])//drive response: disk is present nextstate=DISKPRESENT; else nextstate=DISKCHANGE; end DISKPRESENT://disk is present in flash drive begin trackrd=0; trackwr=0; trackch=1; dmaon=0; blckint=0; _dskchange=1; if (rx_flag && spi_cmd2 && !rx_data[0])//drive response: disk has been removed nextstate=DISKCHANGE; else if(rx_flag && spi_cmd2 && dmaen && !lenzero && enable)//dsklen>0 and dma enabled, do disk dma operation nextstate=DISKDMA; else nextstate=DISKPRESENT; end DISKDMA://do disk dma operation begin trackrd=(~lenzero)&(~dsklen[14]);//track read (disk->ram) trackwr=dsklen[14];//track write (ram->disk) trackch=0; dmaon=(~lenzero)|(~dsklen[14]); blckint=0; _dskchange=1; if (!dmaen || !enable) nextstate = DISKPRESENT; else if (lenzero && bufempty && !bufwr_del)//complete dma cycle done nextstate = DISKINT; else nextstate = DISKDMA; end DISKINT://generate disk dma completed (DSKBLK) interrupt begin trackrd=0; trackwr=0; trackch=0; dmaon=0; blckint=1; _dskchange=1; nextstate=DISKPRESENT; end default://we should never come here begin trackrd=1'bx; trackwr=1'bx; trackch=1'bx; dmaon=1'bx; blckint=1'bx; _dskchange=1'bx; nextstate=DISKCHANGE; end endcase end//--------------------------------------------------------------------------------------endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//8192 words deep, 16 bits wide, fifo//data is written into the fifo when wr=1//reading is more or less asynchronous if you read during the rising edge of clk//because the output data is updated at the falling edge of the clk//when rd=1, the next data word is selected module fifo( input clk, //bus clock input reset, //reset input [15:0]din, //data in output reg [15:0]dout, //data out input rd, //read from fifo input wr, //write to fifo output full, //fifo is full output [13:0]cnt, output reg empty //fifo is empty);//local signals and registersreg [15:0]mem[8191:0]; //8192 words by 16 bit wide fifo memoryreg [13:0]inptr; //fifo input pointerreg [13:0]outptr; //fifo output pointerwire equal; //lower 13 bits of inptr and outptr are equalassign cnt = inptr - outptr;//main fifo memory (implemented using synchronous block ram)always @(posedge clk) if (wr && !full) mem[inptr[12:0]]<=din;always @(posedge clk) dout=mem[outptr[12:0]];//fifo write pointer controlalways @(posedge clk) if(reset) inptr[13:0]<=0; else if(wr && !full) inptr[13:0]<=inptr[13:0]+1;//fifo read pointer controlalways @(posedge clk) if(reset) outptr[13:0]<=0; else if(rd && !empty) outptr[13:0]<=outptr[13:0]+1;//check lower 13 bits of pointer to generate equal signalassign equal=(inptr[12:0]==outptr[12:0])?1:0;//assign output flags, empty is delayed by one clock to handle ram delayalways @(posedge clk) if(equal && (inptr[13]==outptr[13])) empty=1; else empty=0; assign full=(equal && (inptr[13]!=outptr[13]))?1:0; endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -