Revision 70
Added by markw over 11 years ago
user_io.v | ||
---|---|---|
module user_io(
|
||
input SPI_CLK,
|
||
input SPI_SS_IO,
|
||
output reg SPI_MISO,
|
||
input SPI_MOSI,
|
||
input [7:0] CORE_TYPE,
|
||
output [5:0] JOY0,
|
||
output [5:0] JOY1,
|
||
output [127:0] KEYBOARD,
|
||
output [1:0] BUTTONS,
|
||
output [1:0] SWITCHES
|
||
);
|
||
|
||
reg [6:0] sbuf;
|
||
reg [7:0] cmd;
|
||
reg [7:0] cnt;
|
||
reg [5:0] joystick0;
|
||
reg [5:0] joystick1;
|
||
reg [119:0] keyboard;
|
||
reg [127:0] keyboard_out;
|
||
reg [3:0] but_sw;
|
||
|
||
assign JOY0 = joystick0;
|
||
assign JOY1 = joystick1;
|
||
assign KEYBOARD = keyboard_out;
|
||
assign BUTTONS = but_sw[1:0];
|
||
assign SWITCHES = but_sw[3:2];
|
||
|
||
always@(negedge SPI_CLK) begin
|
||
if(SPI_SS_IO == 1) begin
|
||
SPI_MISO <= 1'bZ;
|
||
end else begin
|
||
if(cnt < 8) begin
|
||
SPI_MISO <= CORE_TYPE[7-cnt];
|
||
end else begin
|
||
SPI_MISO <= 1'bZ;
|
||
end
|
||
end
|
||
end
|
||
|
||
always@(posedge SPI_CLK) begin
|
||
if(SPI_SS_IO == 1) begin
|
||
cnt <= 0;
|
||
end else begin
|
||
sbuf[6:1] <= sbuf[5:0];
|
||
sbuf[0] <= SPI_MOSI;
|
||
|
||
cnt <= cnt + 1;
|
||
|
||
if(cnt == 7) begin
|
||
cmd[7:1] <= sbuf;
|
||
cmd[0] <= SPI_MOSI;
|
||
end
|
||
|
||
if(cnt == 15) begin
|
||
if(cmd == 1) begin
|
||
but_sw[3:1] <= sbuf[2:0];
|
||
but_sw[0] <= SPI_MOSI;
|
||
end
|
||
if(cmd == 2) begin
|
||
joystick0[5:1] <= sbuf[4:0];
|
||
joystick0[0] <= SPI_MOSI;
|
||
end
|
||
if(cmd == 3) begin
|
||
joystick1[5:1] <= sbuf[4:0];
|
||
joystick1[0] <= SPI_MOSI;
|
||
end
|
||
end
|
||
// MiST user_io
|
||
|
||
module user_io(
|
||
input SPI_CLK,
|
||
input SPI_SS_IO,
|
||
output reg SPI_MISO,
|
||
input SPI_MOSI,
|
||
|
||
input [7:0] CORE_TYPE,
|
||
|
||
output [5:0] JOY0,
|
||
output [5:0] JOY1,
|
||
output [1:0] BUTTONS,
|
||
output [1:0] SWITCHES,
|
||
|
||
input clk,
|
||
output ps2_clk,
|
||
output reg ps2_data
|
||
);
|
||
|
||
reg [6:0] sbuf;
|
||
reg [7:0] cmd;
|
||
reg [4:0] cnt;
|
||
reg [5:0] joystick0;
|
||
reg [5:0] joystick1;
|
||
reg [3:0] but_sw;
|
||
|
||
assign JOY0 = joystick0;
|
||
assign JOY1 = joystick1;
|
||
assign BUTTONS = but_sw[1:0];
|
||
assign SWITCHES = but_sw[3:2];
|
||
|
||
// drive MISO only when transmitting core id
|
||
always@(negedge SPI_CLK or posedge SPI_SS_IO) begin
|
||
if(SPI_SS_IO == 1) begin
|
||
SPI_MISO <= 1'bZ;
|
||
end else begin
|
||
if(cnt < 8) begin
|
||
SPI_MISO <= CORE_TYPE[7-cnt];
|
||
end else begin
|
||
SPI_MISO <= 1'bZ;
|
||
end
|
||
end
|
||
end
|
||
|
||
// 8 byte fifo to store ps2 bytes
|
||
localparam PS2_FIFO_BITS = 3;
|
||
reg [7:0] ps2_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||
reg [PS2_FIFO_BITS-1:0] ps2_wptr;
|
||
reg [PS2_FIFO_BITS-1:0] ps2_rptr;
|
||
|
||
// ps2 transmitter state machine
|
||
reg [3:0] ps2_tx_state;
|
||
reg [7:0] ps2_tx_byte;
|
||
reg ps2_parity;
|
||
|
||
assign ps2_clk = clk || (ps2_tx_state == 0);
|
||
|
||
|
||
// ps2 transmitter
|
||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||
reg ps2_r_inc;
|
||
always@(posedge clk) begin
|
||
ps2_r_inc <= 1'b0;
|
||
|
||
if(ps2_r_inc)
|
||
ps2_rptr <= ps2_rptr + 1;
|
||
|
||
// transmitter is idle?
|
||
if(ps2_tx_state == 0) begin
|
||
// data in fifo present?
|
||
if(ps2_wptr != ps2_rptr) begin
|
||
// load tx register from fifo
|
||
ps2_tx_byte <= ps2_fifo[ps2_rptr];
|
||
ps2_r_inc <= 1'b1;
|
||
|
||
// 15,23,31,39,47,55,63,71
|
||
if (cnt[2:0]==7) begin
|
||
if(cmd == 5) begin
|
||
if (!cnt[7]) begin
|
||
keyboard[111:0] <= keyboard[119:8];
|
||
keyboard[119:113] <= sbuf[6:0];
|
||
keyboard[112] <= SPI_MOSI;
|
||
end
|
||
if (cnt[7]) begin
|
||
keyboard_out[119:0] <= keyboard[119:0];
|
||
keyboard_out[127:121] <= sbuf[6:0];
|
||
keyboard_out[120] <= SPI_MOSI;
|
||
end
|
||
end
|
||
// reset parity
|
||
ps2_parity <= 1'b1;
|
||
|
||
// start transmitter
|
||
ps2_tx_state <= 4'd1;
|
||
|
||
// put start bit on data line
|
||
ps2_data <= 1'b0; // start bit is 0
|
||
end
|
||
end else begin
|
||
|
||
// transmission of 8 data bits
|
||
if((ps2_tx_state >= 1)&&(ps2_tx_state < 9)) begin
|
||
ps2_data <= ps2_tx_byte[0]; // data bits
|
||
ps2_tx_byte[6:0] <= ps2_tx_byte[7:1]; // shift down
|
||
if(ps2_tx_byte[0])
|
||
ps2_parity <= !ps2_parity;
|
||
end
|
||
|
||
// transmission of parity
|
||
if(ps2_tx_state == 9)
|
||
ps2_data <= ps2_parity;
|
||
|
||
// transmission of stop bit
|
||
if(ps2_tx_state == 10)
|
||
ps2_data <= 1'b1; // stop bit is 1
|
||
|
||
// advance state machine
|
||
if(ps2_tx_state < 11)
|
||
ps2_tx_state <= ps2_tx_state + 4'd1;
|
||
else
|
||
ps2_tx_state <= 4'd0;
|
||
|
||
end
|
||
end
|
||
|
||
// SPI receiver
|
||
//reg ps2_w_inc;
|
||
always@(posedge SPI_CLK or posedge SPI_SS_IO) begin
|
||
// ps2_w_inc <= 1'b0;
|
||
// if(ps2_w_inc)
|
||
// ps2_wptr <= ps2_wptr + 1;
|
||
|
||
if(SPI_SS_IO == 1) begin
|
||
cnt <= 1'b0;
|
||
end else begin
|
||
sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
|
||
// counter counts 0-7, 8-15, 8-15 ...
|
||
// 0-7 is command, 8-15 is payload
|
||
if(cnt != 15) cnt <= cnt + 4'd1;
|
||
else cnt <= 4'd8;
|
||
|
||
// finished reading command byte
|
||
if(cnt == 7)
|
||
cmd <= { sbuf, SPI_MOSI};
|
||
|
||
if(cnt == 15) begin
|
||
if(cmd == 1)
|
||
but_sw <= { sbuf[2:0], SPI_MOSI };
|
||
|
||
if(cmd == 2)
|
||
joystick0 <= { sbuf[4:0], SPI_MOSI };
|
||
|
||
if(cmd == 3)
|
||
joystick1 <= { sbuf[4:0], SPI_MOSI };
|
||
|
||
if(cmd == 5) begin
|
||
// store incoming keyboard bytes in
|
||
ps2_fifo[ps2_wptr] <= { sbuf, SPI_MOSI };
|
||
ps2_wptr <= ps2_wptr + 1;
|
||
end
|
||
end
|
||
end
|
||
// always@(posedge clk2) begin
|
||
// LED <= ~LED;
|
||
// end
|
||
|
||
endmodule
|
||
|
||
end
|
||
end
|
||
end
|
||
|
||
endmodule
|
Added ZPU. Added read/write SD support. Fixed joystick. Switched to new mist keyboard mode (ps2 emulation).