📄 userio.v
字号:
if (rx && cmd && wrdat[7:5]==3'b001)//set linenumber from incoming command byte wraddr[9:0] <= {wrdat[2:0],7'b0000000}; else if (rx) //increment for every data byte that comes in wraddr[9:0] <= wraddr[9:0] + 1;always @(posedge clk) if (~osdenable1) highlight <= 4'b1000; else if (rx && cmd && wrdat[7:4]==4'b0011) highlight <= wrdat[3:0]; //disable/enable osd displayalways @(posedge clk)begin if(spicmd[2:0]==3'b010)//disable osdenable1 <= 0; else if(spicmd[2:0]==3'b011)//enable osdenable1 <= 1;end//synchronize osdenable 1 to start-of-framealways @(posedge clk) osdenable2 <= osdenable1; assign osdenable = osdenable2;assign wren = rx && ~cmd && spicmd==3'b001 ? 1 : 0;//user reset request (from osd menu) assign usrrst = rx && cmd && wrdat[7:5]==3'b100 ? 1 : 0;//reset to bootloaderassign bootrst = rx && cmd && wrdat[7:5]==3'b100 && wrdat[0] ? 1 : 0;endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//SPI interface module (8 bits)//this is a slave module, clock is controlled by host//clock is high when bus is idle//ingoing data is sampled at the positive clock edge//outgoing data is shifted/changed at the negative clock edge//msb is sent first// ____ _ _ _ _//dclk -> |_| |_| |_| |_|//data -> 777 666 555 444//sample -> ^ ^ ^ ^//strobe is asserted at the end of every byte and signals that new data must//be registered at the out output. At the same time, new data is read from the in input.//The data at input in is also sent as the first byte after _den is asserted (without strobe!). module spi8( input clk, //pixel clock input scs, //SPI chip select input sdi, //SPI data in output sdo, //SPI data out input sck, //SPI clock input [7:0]in, //parallel input data output [7:0]out, //parallel output data output reg rx, //byte received output reg cmd //first byte received);//localsreg [2:0]bit_cnt; //bit counterreg [7:0]sdi_reg; //input shift register (rising edge of SPI clock)reg sdo_reg; //output shift register (falling edge of SPI clock)reg new_byte; //new byte (8 bits) receivedreg rx_sync; //synchronization to clk (first stage)reg first_byte; //first byte is going to be received//------ input shift register ------//always @(posedge sck) sdi_reg <= {sdi_reg[6:0],sdi};assign out = sdi_reg;//------ receive bit counter ------//always @(posedge sck or negedge scs) if (~scs) bit_cnt <= 0; //always clear bit counter when CS is not active else bit_cnt <= bit_cnt + 1; //increment bit counter when new bit has been received//----- rx signal ------////this signal goes high for one clk clock period just after new byte has been received//it's synchronous with clk, output data shouldn't change when rx is activealways @(posedge sck or posedge rx) if (rx) new_byte <= 0; //cleared asynchronously when rx is high (rx is synchronous with clk) else if (bit_cnt==7) new_byte <= 1; //set when last bit of a new byte has been just receivedalways @(negedge clk) rx_sync <= new_byte; //double synchronization to avoid metastabilityalways @(posedge clk) rx <= rx_sync; //synchronous with clk//------ cmd signal generation ------////this signal becomes active after reception of first byte//when any other byte is received it's deactivated indicating data bytesalways @(posedge sck or negedge scs) if (~scs) first_byte <= 1; //set when CS is not active else if (bit_cnt==7) first_byte <= 0; //cleared after reception of first bytealways @(posedge sck) if (bit_cnt==7) cmd <= first_byte; //active only when first byte received //------ serial data output register ------//always @(negedge sck) //output change on falling SPI clock sdo_reg <= in[~bit_cnt[1:0]];//------ SPI output signal ------//assign sdo = scs & sdo_reg; //force zero if SPI not selectedendmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//PS2 mouse controller.//This module decodes the standard 3 byte packet of an PS/2 compatible 2 or 3 button mouse.//The module also automatically handles power-up initailzation of the mouse.module ps2mouse( input clk, //bus clock input reset, //reset inout ps2mdat, //mouse PS/2 data inout ps2mclk, //mouse PS/2 clk output reg [7:0]ycount, //mouse Y counter output reg [7:0]xcount, //mouse X counter output reg _mleft, //left mouse button output output reg _mthird, //third(middle) mouse button output output reg _mright, //right mouse button output input test_load, //load test value to mouse counter input [15:0]test_data //mouse counter test value);//local signalsreg mclkout; //mouse clk outwire mdatout; //mouse data outreg mdatb,mclkb,mclkc; //input synchronization reg [10:0]mreceive; //mouse receive register reg [11:0]msend; //mouse send registerreg [15:0]mtimer; //mouse timerreg [2:0]mstate; //mouse current statereg [2:0]mnext; //mouse next statewire mclkneg; //negative edge of mouse clock strobereg mrreset; //mouse receive resetwire mrready; //mouse receive ready;reg msreset; //mosue send resetwire msready; //mouse send ready;reg mtreset; //mouse timer resetwire mtready; //mouse timer ready wire mthalf; //mouse timer somewhere halfway timeoutreg [1:0]mpacket; //mouse packet byte valid number//bidirectional open collector IO buffersassign ps2mclk=(mclkout)?1'bz:1'b0;assign ps2mdat=(mdatout)?1'bz:1'b0;//input synchronization of external signalsalways @(posedge clk)begin mdatb<=ps2mdat; mclkb<=ps2mclk; mclkc<=mclkb;end //detect mouse clock negative edgeassign mclkneg=mclkc&(~mclkb);//PS2 mouse input shifteralways @(posedge clk) if(mrreset) mreceive[10:0]<=11'b11111111111; else if(mclkneg) mreceive[10:0]<={mdatb,mreceive[10:1]};assign mrready=~mreceive[0];//PS2 mouse send shifteralways @(posedge clk) if(msreset) msend[11:0]<=12'b110111101000; else if(!msready && mclkneg) msend[11:0]<={1'b0,msend[11:1]};assign msready=(msend[11:0]==12'b000000000001)?1:0;assign mdatout=msend[0];//PS2 mouse timeralways @(posedge clk) if(mtreset) mtimer[15:0]<=16'h0000; else mtimer[15:0]<=mtimer[15:0]+1;assign mtready=(mtimer[15:0]==16'hffff)?1:0;assign mthalf=mtimer[11];//PS2 mouse packet decoding and handlingalways @(posedge clk)begin if(reset)//reset begin {_mthird,_mright,_mleft}<=3'b111; xcount[7:0]<=8'h00; ycount[7:0]<=8'h00; end else if (test_load) //test value preload {ycount[7:2],xcount[7:2]} <= {test_data[15:10],test_data[7:2]}; else if(mpacket==1)//buttons {_mthird,_mright,_mleft}<=~mreceive[3:1]; else if(mpacket==2)//delta X movement xcount[7:0]<=xcount[7:0]+mreceive[8:1]; else if(mpacket==3)//delta Y movement ycount[7:0]<=ycount[7:0]-mreceive[8:1];end//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//PS2 mouse state machinealways @(posedge clk) if(reset || mtready)//master reset OR timeout mstate<=0; else mstate<=mnext;always @(mstate or mthalf or msready or mrready or mreceive)begin case(mstate) 0://initialize mouse phase 0, start timer begin mclkout=1; mrreset=0; mtreset=1; msreset=0; mpacket=0; mnext=1; end 1://initialize mouse phase 1, hold clk low and reset send logic begin mclkout=0; mrreset=0; mtreset=0; msreset=1; mpacket=0; if(mthalf)//clk was low long enough, go to next state mnext=2; else mnext=1; end 2://initialize mouse phase 2, send 'enable data reporting' command to mouse begin mclkout=1; mrreset=1; mtreset=0; msreset=0; mpacket=0; if(msready)//command set, go get 'ack' byte mnext=5; else mnext=2; end 3://get first packet byte begin mclkout=1; mtreset=1; msreset=0; if(mrready)//we got our first packet byte begin mpacket=1; mrreset=1; mnext=4; end else//we are still waiting begin mpacket=0; mrreset=0; mnext=3; end end 4://get second packet byte begin mclkout=1; mtreset=0; msreset=0; if(mrready)//we got our second packet byte begin mpacket=2; mrreset=1; mnext=5; end else//we are still waiting begin mpacket=0; mrreset=0; mnext=4; end end 5://get third packet byte (or get 'ACK' byte..) begin mclkout=1; mtreset=0; msreset=0; if(mrready)//we got our third packet byte begin mpacket=3; mrreset=1; mnext=3; end else//we are still waiting begin mpacket=0; mrreset=0; mnext=5; end end default://we should never come here begin mclkout=1'bx; mrreset=1'bx; mtreset=1'bx; msreset=1'bx; mpacket=2'bxx; mnext=0; end endcaseend//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -