📄 ps2_mouse.v
字号:
or q
or tx_shifting_done
or tx_write
or ps2_clk_s
or ps2_data_s
or timer_60usec_done
or timer_5usec_done
)
begin : m1_state_logic
// Output signals default to this value, unless changed in a state condition.
ps2_clk_hi_z <= #1 1;
ps2_data_hi_z <= #1 1;
tx_error_no_ack <= #1 0;
enable_timer_60usec <= #1 0;
enable_timer_5usec <= #1 0;
case (m1_state)
m1_rx_clk_h :
begin
enable_timer_60usec <= #1 1;
if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
else if (~ps2_clk_s) m1_next_state <= #1 m1_rx_falling_edge_marker;
else m1_next_state <= #1 m1_rx_clk_h;
end
m1_rx_falling_edge_marker :
begin
enable_timer_60usec <= #1 0;
m1_next_state <= #1 m1_rx_clk_l;
end
m1_rx_rising_edge_marker :
begin
enable_timer_60usec <= #1 0;
m1_next_state <= #1 m1_rx_clk_h;
end
m1_rx_clk_l :
begin
enable_timer_60usec <= #1 1;
if (tx_write) m1_next_state <= #1 m1_tx_reset_timer;
else if (ps2_clk_s) m1_next_state <= #1 m1_rx_rising_edge_marker;
else m1_next_state <= #1 m1_rx_clk_l;
end
m1_tx_reset_timer:
begin
enable_timer_60usec <= #1 0;
m1_next_state <= #1 m1_tx_force_clk_l;
end
m1_tx_force_clk_l :
begin
enable_timer_60usec <= #1 1;
ps2_clk_hi_z <= #1 0; // Force the ps2_clk line low.
if (timer_60usec_done) m1_next_state <= #1 m1_tx_first_wait_clk_h;
else m1_next_state <= #1 m1_tx_force_clk_l;
end
m1_tx_first_wait_clk_h :
begin
enable_timer_5usec <= #1 1;
ps2_data_hi_z <= #1 0; // Start bit.
if (~ps2_clk_s && timer_5usec_done)
m1_next_state <= #1 m1_tx_clk_l;
else
m1_next_state <= #1 m1_tx_first_wait_clk_h;
end
// This state must be included because the device might possibly
// delay for up to 10 milliseconds before beginning its clock pulses.
// During that waiting time, we cannot drive the data (q[0]) because it
// is possibly 1, which would cause the keyboard to abort its receive
// and the expected clocks would then never be generated.
m1_tx_first_wait_clk_l :
begin
ps2_data_hi_z <= #1 0;
if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
else m1_next_state <= #1 m1_tx_first_wait_clk_l;
end
m1_tx_wait_clk_h :
begin
enable_timer_5usec <= #1 1;
ps2_data_hi_z <= #1 q[0];
if (ps2_clk_s && timer_5usec_done)
m1_next_state <= #1 m1_tx_rising_edge_marker;
else
m1_next_state <= #1 m1_tx_wait_clk_h;
end
m1_tx_rising_edge_marker :
begin
ps2_data_hi_z <= #1 q[0];
m1_next_state <= #1 m1_tx_clk_h;
end
m1_tx_clk_h :
begin
ps2_data_hi_z <= #1 q[0];
if (tx_shifting_done) m1_next_state <= #1 m1_tx_wait_ack;
else if (~ps2_clk_s) m1_next_state <= #1 m1_tx_clk_l;
else m1_next_state <= #1 m1_tx_clk_h;
end
m1_tx_clk_l :
begin
ps2_data_hi_z <= #1 q[0];
if (ps2_clk_s) m1_next_state <= #1 m1_tx_wait_clk_h;
else m1_next_state <= #1 m1_tx_clk_l;
end
m1_tx_wait_ack :
begin
if (~ps2_clk_s && ps2_data_s)
m1_next_state <= #1 m1_tx_error_no_ack;
else if (~ps2_clk_s && ~ps2_data_s)
m1_next_state <= #1 m1_tx_done_recovery;
else m1_next_state <= #1 m1_tx_wait_ack;
end
m1_tx_done_recovery :
begin
if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
else m1_next_state <= #1 m1_tx_done_recovery;
end
m1_tx_error_no_ack :
begin
tx_error_no_ack <= #1 1;
if (ps2_clk_s && ps2_data_s) m1_next_state <= #1 m1_rx_clk_h;
else m1_next_state <= #1 m1_tx_error_no_ack;
end
default : m1_next_state <= #1 m1_rx_clk_h;
endcase
end
// State register
always @(posedge clk)
begin : m2_state_register
if (reset) m2_state <= #1 m2_rx_data_ready_ack;
else m2_state <= #1 m2_next_state;
end
// State transition logic
always @(m2_state or rx_output_strobe or rx_read)
begin : m2_state_logic
case (m2_state)
m2_rx_data_ready_ack:
begin
rx_data_ready <= #1 1'b0;
if (rx_output_strobe) m2_next_state <= #1 m2_rx_data_ready;
else m2_next_state <= #1 m2_rx_data_ready_ack;
end
m2_rx_data_ready:
begin
rx_data_ready <= #1 1'b1;
if (rx_read) m2_next_state <= #1 m2_rx_data_ready_ack;
else m2_next_state <= #1 m2_rx_data_ready;
end
default : m2_next_state <= #1 m2_rx_data_ready_ack;
endcase
end
// This is the bit counter
always @(posedge clk)
begin
if ( reset
|| rx_shifting_done
|| (m1_state == m1_tx_wait_ack) // After tx is done.
) bit_count <= #1 0; // normal reset
else if (timer_60usec_done
&& (m1_state == m1_rx_clk_h)
&& (ps2_clk_s)
) bit_count <= #1 0; // rx watchdog timer reset
else if ( (m1_state == m1_rx_falling_edge_marker) // increment for rx
||(m1_state == m1_tx_rising_edge_marker) // increment for tx
)
bit_count <= #1 bit_count + 1;
end
// This signal is high for one clock at the end of the timer count.
assign rx_shifting_done = (bit_count == `TOTAL_BITS);
assign tx_shifting_done = (bit_count == `TOTAL_BITS-1);
// This is the signal which enables loading of the shift register.
// It also indicates "ack" to the device writing to the transmitter.
assign tx_write_ack_o = ( (tx_write && (m1_state == m1_rx_clk_h))
||(tx_write && (m1_state == m1_rx_clk_l))
);
// This is the ODD parity bit for the transmitted word.
assign tx_parity_bit = ~^tx_data;
// This is the shift register
always @(posedge clk)
begin
if (reset) q <= #1 0;
else if (tx_write_ack_o) q <= #1 {1'b1,tx_parity_bit,tx_data,1'b0};
else if ( (m1_state == m1_rx_falling_edge_marker)
||(m1_state == m1_tx_rising_edge_marker) )
q <= #1 {ps2_data_s,q[`TOTAL_BITS-1:1]};
end
// This is the 60usec timer counter
always @(posedge clk)
begin
if (~enable_timer_60usec) timer_60usec_count <= #1 0;
else if ( timer_done && !timer_60usec_done)
timer_60usec_count<= #1 timer_60usec_count +1;
end
assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP ));
always @(posedge clk or posedge reset)
if (reset) timer_5usec <= #1 1;
else if (!enable_timer_60usec) timer_5usec <= #1 1;
else if (timer_5usec == devide_reg_i)
begin
timer_5usec <= #1 1;
timer_done <= #1 1;
end
else
begin
timer_5usec<= #1 timer_5usec +1;
timer_done <= #1 0;
end
// This is the 5usec timer counter
always @(posedge clk)
begin
if (~enable_timer_5usec) timer_5usec_count <= #1 0;
else if (~timer_5usec_done) timer_5usec_count <= #1 timer_5usec_count + 1;
end
assign timer_5usec_done = (timer_5usec_count == devide_reg_i - 1);
always @(posedge clk)
begin
if (reset)
begin
rx_scan_code <= #1 0;
end
else if (rx_output_strobe)
begin
rx_scan_code <= #1 q[8:1];
end
end
// Store the final rx output data only when all extend and release codes
// are received and the next (actual key) scan code is also ready.
// (the presence of rx_extended or rx_released refers to the
// the current latest scan code received, not the previously latched flags.)
assign rx_output_event = rx_shifting_done ;
assign rx_output_strobe = rx_shifting_done ;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -