📄 paula.v
字号:
intena[14:0]<=intena[14:0]|datain[14:0]; else intena[14:0]<=intena[14:0]&(~datain[14:0]); end//intenar registeralways @(regaddress or intena) if(regaddress[8:1]==INTENAR[8:1]) intenar[15:0]={1'b0,intena[14:0]}; else intenar=0;//intreqr registeralways @(regaddress or intreq) if(regaddress[8:1]==INTREQR[8:1]) intreqr[15:0]={2'b00,intreq[13:0]}; else intreqr=0;// control all interrupts, intterupts are registered at the rising edge of clkreg [13:0]tmp;always @(regaddress or datain or intreq) //check if we are addressed and some bits must change //(generate mask tmp[13:0]) if(regaddress[8:1]==INTREQ[8:1]) begin if(datain[15]) tmp[13:0]=intreq[13:0]|datain[13:0]; else tmp[13:0]=intreq[13:0]&(~datain[13:0]); end else tmp[13:0]=intreq[13:0];always @(posedge clk)begin if(reset)//synchronous reset intreq<=0; else begin //transmit buffer empty interrupt intreq[0]<=tmp[0]|txint; //diskblock finished intreq[1]<=tmp[1]|blckint; //software interrupt intreq[2]<=tmp[2]; //I/O ports and timers intreq[3]<=tmp[3]|int2; //Copper intreq[4]<=tmp[4]; //start of vertical blank intreq[5]<=tmp[5]|sof; //blitter finished intreq[6]<=tmp[6]|int3; //audio channel 0 intreq[7]<=tmp[7]|audint[0]; //audio channel 1 intreq[8]<=tmp[8]|audint[1]; //audio channel 2 intreq[9]<=tmp[9]|audint[2]; //audio channel 3 intreq[10]<=tmp[10]|audint[3]; //serial port receive interrupt intreq[11]<=tmp[11]|rxint; //disk sync register matches disk data intreq[12]<=tmp[12]|syncint; //external interrupt intreq[13]<=tmp[13]|int6; endend //create m68k interrupt request signalsreg [13:0]intreqena;always @(intena or intreq)begin //and int enable and request signals together if(intena[14]) intreqena[13:0]=intreq[13:0]&intena[13:0]; else intreqena[13:0]=14'b00000000000000; end//interrupt priority encoderalways @(posedge clk)begin casez(intreqena[13:0]) 14'b1????????????? : _ipl<=1; 14'b01???????????? : _ipl<=2; 14'b001??????????? : _ipl<=2; 14'b0001?????????? : _ipl<=3; 14'b00001????????? : _ipl<=3; 14'b000001???????? : _ipl<=3; 14'b0000001??????? : _ipl<=3; 14'b00000001?????? : _ipl<=4; 14'b000000001????? : _ipl<=4; 14'b0000000001???? : _ipl<=4; 14'b00000000001??? : _ipl<=5; 14'b000000000001?? : _ipl<=6; 14'b0000000000001? : _ipl<=6; 14'b00000000000001 : _ipl<=6; 14'b00000000000000 : _ipl<=7; default: _ipl<=7; endcaseendendmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//Simplified uart//NOTES://not supported are 9 databits mode and overrun detection for the receiver//also the behaviour of tsre is not completely according to the amiga hardware//reference manual, it should work thoughmodule uart(clk,reset,regaddress,datain,dataout,rbfmirror,rxint,txint,rxd,txd);input clk; //bus clockinput reset; //reset input [8:1] regaddress; //register address inputsinput [14:0]datain; //bus data inoutput [15:0]dataout; //bus data outinput rbfmirror; //rbf mirror from interrupt controlleroutput txint; //transmitter intterruptoutput rxint; //receiver intteruptoutput txd; //serial port transmitted datainput rxd; //serial port received data//register names and addressesparameter SERDAT=9'h030; parameter SERDATR=9'h018;parameter SERPER=9'h032;//local signal for txreg [14:0]serper; //period (baud rate) registerreg [15:0]txdiv; //transmitter baud rate dividerreg [10:0]serdat; //serdat registerreg [11:0]txshift; //transmit shifterreg [1:0]txstate; //transmitter statereg [1:0]txnextstate; //next transmitter statewire txbaud; //transmitter baud clockreg txload; //load transmit shifterreg tsre; //transmit shift register emptyreg tbe; //transmit buffer emptyreg txint; //see above//local signals for rxreg [15:0]rxdiv; //receiver baud rate dividerreg [9:0]rxshift; //receiver shift registerreg [7:0]rxdat; //received data bufferreg [1:0]rxstate; //receiver statereg [1:0]rxnextstate; //next receiver statewire rxbaud; //receiver baud clockreg rxpreset; //preset receiver baud clock reg lrxd1; //latched rxd signalreg lrxd2; //latched rxd signalreg rxint; //see abovereg [15:0]dataout; //see above//serper registeralways @(posedge clk) if(regaddress[8:1]==SERPER[8:1]) serper[14:0]<=datain[14:0]; //tx baudrate generatoralways @(posedge clk) if(txbaud) txdiv[15:0]<={serper[14:0],1'b0};//serper shifted right because of 7.09MHz clock else txdiv<=txdiv-1;assign txbaud=(txdiv==0)?1:0;//txd shifteralways @(posedge clk) if(reset) txshift[11:0]<=12'b000000000001; else if(txload && txbaud) txshift[11:0]<={serdat[10:0],1'b0}; else if(!tsre && txbaud) txshift[11:0]<={1'b0,txshift[11:1]};assign txd=txshift[0];//generate tsre signalalways @(txshift[11:0]) if(txshift[11:0]==12'b000000000001) tsre=1; else tsre=0;//serdat registeralways @(posedge clk) if(regaddress[8:1]==SERDAT[8:1]) serdat[10:0]<=datain[10:0];//transmitter state machinealways @(posedge clk) if(reset) txstate<=2'b00; else txstate<=txnextstate;always @(txstate or tsre or regaddress)begin case(txstate) 2'b00://wait for new data and go to next state if serdat is loaded begin txint=0; txload=0; tbe=1; if(regaddress[8:1]==SERDAT[8:1]) txnextstate=2'b01; else txnextstate=2'b00; end 2'b01://wait for shift register to become empty (tsre goes high) begin txint=0; txload=0; tbe=0; if(tsre) txnextstate=2'b10; else txnextstate=2'b01; end 2'b10://wait for shift register to read serdat (tsre goes low) begin txint=0; txload=1; tbe=0; if(!tsre) txnextstate=2'b11; else txnextstate=2'b10; end 2'b11://serdat is now empty again, generate interupt begin txint=1; txload=0; tbe=0; txnextstate=2'b00; end endcase end//rx baud rate generatoralways @(posedge clk) if(rxpreset) rxdiv[15:0]<={1'b0,serper[14:0]}; else if(rxbaud) rxdiv[15:0]<={serper[14:0],1'b0};//serper shifted right because of 7.09MHz clock else rxdiv<=rxdiv-1;assign rxbaud=(rxdiv==0)?1:0;//rxd input synchronizer latchalways @(posedge clk)begin lrxd1<=rxd; lrxd2<=lrxd1;end//receiver shift registeralways @(posedge clk) if(rxpreset) rxshift[9:0]<=10'b1111111111; else if(rxbaud) rxshift[9:0]<={lrxd2,rxshift[9:1]}; //receiver bufferalways @(posedge clk) if(rxint) rxdat[7:0]<=rxshift[8:1];//receiver state machinealways @(posedge clk) if(reset) rxstate<=2'b00; else rxstate<=rxnextstate;always @(rxstate or lrxd2 or rxshift[0])begin case(rxstate) 2'b00://wait for startbit begin rxint=0; rxpreset=1; if(!lrxd2) rxnextstate=2'b01; else rxnextstate=2'b00; end 2'b01://shift in 10 bits (start, 8 data, stop) begin rxint=0; rxpreset=0; if(!rxshift[0]) rxnextstate=2'b10; else rxnextstate=2'b01; end 2'b10,2'b11://new byte has been received, latch byte and request interrupt begin rxint=1; rxpreset=0; rxnextstate=2'b00; end endcaseend //serdatr registeralways @(regaddress or rbfmirror or tbe or tsre or lrxd2 or rxdat) if(regaddress[8:1]==SERDATR[8:1]) dataout[15:0]={1'b0,rbfmirror,tbe,tsre,lrxd2,3'b001,rxdat[7:0]}; else dataout[15:0]=0;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -