Convert tabs to spaces
This commit is contained in:
parent
c2c8ec302e
commit
3e71036abc
@ -1,11 +1,11 @@
|
|||||||
module KeyboardDecoder(
|
module KeyboardDecoder(
|
||||||
output reg [511:0] key_down,
|
output reg [511:0] key_down,
|
||||||
output wire [8:0] last_change,
|
output wire [8:0] last_change,
|
||||||
output reg key_valid,
|
output reg key_valid,
|
||||||
inout wire PS2_DATA,
|
inout wire PS2_DATA,
|
||||||
inout wire PS2_CLK,
|
inout wire PS2_CLK,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
input wire clk
|
input wire clk
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter [1:0] INIT = 2'b00;
|
parameter [1:0] INIT = 2'b00;
|
||||||
@ -13,7 +13,7 @@ module KeyboardDecoder(
|
|||||||
parameter [1:0] GET_SIGNAL_DOWN = 2'b10;
|
parameter [1:0] GET_SIGNAL_DOWN = 2'b10;
|
||||||
parameter [1:0] WAIT_RELEASE = 2'b11;
|
parameter [1:0] WAIT_RELEASE = 2'b11;
|
||||||
|
|
||||||
parameter [7:0] IS_INIT = 8'hAA;
|
parameter [7:0] IS_INIT = 8'hAA;
|
||||||
parameter [7:0] IS_EXTEND = 8'hE0;
|
parameter [7:0] IS_EXTEND = 8'hE0;
|
||||||
parameter [7:0] IS_BREAK = 8'hF0;
|
parameter [7:0] IS_BREAK = 8'hF0;
|
||||||
|
|
||||||
@ -32,104 +32,104 @@ module KeyboardDecoder(
|
|||||||
assign last_change = {key[9], key[7:0]};
|
assign last_change = {key[9], key[7:0]};
|
||||||
|
|
||||||
KeyboardCtrl_0 inst (
|
KeyboardCtrl_0 inst (
|
||||||
.key_in(key_in),
|
.key_in(key_in),
|
||||||
.is_extend(is_extend),
|
.is_extend(is_extend),
|
||||||
.is_break(is_break),
|
.is_break(is_break),
|
||||||
.valid(valid),
|
.valid(valid),
|
||||||
.err(err),
|
.err(err),
|
||||||
.PS2_DATA(PS2_DATA),
|
.PS2_DATA(PS2_DATA),
|
||||||
.PS2_CLK(PS2_CLK),
|
.PS2_CLK(PS2_CLK),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
.clk(clk)
|
.clk(clk)
|
||||||
);
|
);
|
||||||
|
|
||||||
OnePulse op (
|
OnePulse op (
|
||||||
.signal_single_pulse(pulse_been_ready),
|
.signal_single_pulse(pulse_been_ready),
|
||||||
.signal(been_ready),
|
.signal(been_ready),
|
||||||
.clock(clk)
|
.clock(clk)
|
||||||
);
|
);
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
state <= INIT;
|
state <= INIT;
|
||||||
been_ready <= 1'b0;
|
been_ready <= 1'b0;
|
||||||
been_extend <= 1'b0;
|
been_extend <= 1'b0;
|
||||||
been_break <= 1'b0;
|
been_break <= 1'b0;
|
||||||
key <= 10'b0_0_0000_0000;
|
key <= 10'b0_0_0000_0000;
|
||||||
end else begin
|
end else begin
|
||||||
state <= next_state;
|
state <= next_state;
|
||||||
been_ready <= next_been_ready;
|
been_ready <= next_been_ready;
|
||||||
been_extend <= next_been_extend;
|
been_extend <= next_been_extend;
|
||||||
been_break <= next_been_break;
|
been_break <= next_been_break;
|
||||||
key <= next_key;
|
key <= next_key;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
case (state)
|
case (state)
|
||||||
INIT: next_state = (key_in == IS_INIT) ? WAIT_FOR_SIGNAL : INIT;
|
INIT: next_state = (key_in == IS_INIT) ? WAIT_FOR_SIGNAL : INIT;
|
||||||
WAIT_FOR_SIGNAL: next_state = (valid == 1'b0) ? WAIT_FOR_SIGNAL : GET_SIGNAL_DOWN;
|
WAIT_FOR_SIGNAL: next_state = (valid == 1'b0) ? WAIT_FOR_SIGNAL : GET_SIGNAL_DOWN;
|
||||||
GET_SIGNAL_DOWN: next_state = WAIT_RELEASE;
|
GET_SIGNAL_DOWN: next_state = WAIT_RELEASE;
|
||||||
WAIT_RELEASE: next_state = (valid == 1'b1) ? WAIT_RELEASE : WAIT_FOR_SIGNAL;
|
WAIT_RELEASE: next_state = (valid == 1'b1) ? WAIT_RELEASE : WAIT_FOR_SIGNAL;
|
||||||
default: next_state = INIT;
|
default: next_state = INIT;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
next_been_ready = been_ready;
|
next_been_ready = been_ready;
|
||||||
case (state)
|
case (state)
|
||||||
INIT: next_been_ready = (key_in == IS_INIT) ? 1'b0 : next_been_ready;
|
INIT: next_been_ready = (key_in == IS_INIT) ? 1'b0 : next_been_ready;
|
||||||
WAIT_FOR_SIGNAL: next_been_ready = (valid == 1'b0) ? 1'b0 : next_been_ready;
|
WAIT_FOR_SIGNAL: next_been_ready = (valid == 1'b0) ? 1'b0 : next_been_ready;
|
||||||
GET_SIGNAL_DOWN: next_been_ready = 1'b1;
|
GET_SIGNAL_DOWN: next_been_ready = 1'b1;
|
||||||
WAIT_RELEASE: next_been_ready = next_been_ready;
|
WAIT_RELEASE: next_been_ready = next_been_ready;
|
||||||
default: next_been_ready = 1'b0;
|
default: next_been_ready = 1'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
next_been_extend = (is_extend) ? 1'b1 : been_extend;
|
next_been_extend = (is_extend) ? 1'b1 : been_extend;
|
||||||
case (state)
|
case (state)
|
||||||
INIT: next_been_extend = (key_in == IS_INIT) ? 1'b0 : next_been_extend;
|
INIT: next_been_extend = (key_in == IS_INIT) ? 1'b0 : next_been_extend;
|
||||||
WAIT_FOR_SIGNAL: next_been_extend = next_been_extend;
|
WAIT_FOR_SIGNAL: next_been_extend = next_been_extend;
|
||||||
GET_SIGNAL_DOWN: next_been_extend = next_been_extend;
|
GET_SIGNAL_DOWN: next_been_extend = next_been_extend;
|
||||||
WAIT_RELEASE: next_been_extend = (valid == 1'b1) ? next_been_extend : 1'b0;
|
WAIT_RELEASE: next_been_extend = (valid == 1'b1) ? next_been_extend : 1'b0;
|
||||||
default: next_been_extend = 1'b0;
|
default: next_been_extend = 1'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
next_been_break = (is_break) ? 1'b1 : been_break;
|
next_been_break = (is_break) ? 1'b1 : been_break;
|
||||||
case (state)
|
case (state)
|
||||||
INIT: next_been_break = (key_in == IS_INIT) ? 1'b0 : next_been_break;
|
INIT: next_been_break = (key_in == IS_INIT) ? 1'b0 : next_been_break;
|
||||||
WAIT_FOR_SIGNAL: next_been_break = next_been_break;
|
WAIT_FOR_SIGNAL: next_been_break = next_been_break;
|
||||||
GET_SIGNAL_DOWN: next_been_break = next_been_break;
|
GET_SIGNAL_DOWN: next_been_break = next_been_break;
|
||||||
WAIT_RELEASE: next_been_break = (valid == 1'b1) ? next_been_break : 1'b0;
|
WAIT_RELEASE: next_been_break = (valid == 1'b1) ? next_been_break : 1'b0;
|
||||||
default: next_been_break = 1'b0;
|
default: next_been_break = 1'b0;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
next_key = key;
|
next_key = key;
|
||||||
case (state)
|
case (state)
|
||||||
INIT: next_key = (key_in == IS_INIT) ? 10'b0_0_0000_0000 : next_key;
|
INIT: next_key = (key_in == IS_INIT) ? 10'b0_0_0000_0000 : next_key;
|
||||||
WAIT_FOR_SIGNAL: next_key = next_key;
|
WAIT_FOR_SIGNAL: next_key = next_key;
|
||||||
GET_SIGNAL_DOWN: next_key = {been_extend, been_break, key_in};
|
GET_SIGNAL_DOWN: next_key = {been_extend, been_break, key_in};
|
||||||
WAIT_RELEASE: next_key = next_key;
|
WAIT_RELEASE: next_key = next_key;
|
||||||
default: next_key = 10'b0_0_0000_0000;
|
default: next_key = 10'b0_0_0000_0000;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
key_valid <= 1'b0;
|
key_valid <= 1'b0;
|
||||||
key_down <= 511'b0;
|
key_down <= 511'b0;
|
||||||
end else if (key_decode[last_change] && pulse_been_ready) begin
|
end else if (key_decode[last_change] && pulse_been_ready) begin
|
||||||
key_valid <= 1'b1;
|
key_valid <= 1'b1;
|
||||||
if (key[8] == 0) begin
|
if (key[8] == 0) begin
|
||||||
key_down <= key_down | key_decode;
|
key_down <= key_down | key_decode;
|
||||||
end else begin
|
end else begin
|
||||||
key_down <= key_down & (~key_decode);
|
key_down <= key_down & (~key_decode);
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
key_valid <= 1'b0;
|
key_valid <= 1'b0;
|
||||||
key_down <= key_down;
|
key_down <= key_down;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
module OnePulse (
|
module OnePulse (
|
||||||
output reg signal_single_pulse,
|
output reg signal_single_pulse,
|
||||||
input wire signal,
|
input wire signal,
|
||||||
input wire clock
|
input wire clock
|
||||||
);
|
);
|
||||||
|
|
||||||
reg signal_delay;
|
reg signal_delay;
|
||||||
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if (signal == 1'b1 & signal_delay == 1'b0)
|
if (signal == 1'b1 & signal_delay == 1'b0)
|
||||||
signal_single_pulse <= 1'b1;
|
signal_single_pulse <= 1'b1;
|
||||||
else
|
else
|
||||||
signal_single_pulse <= 1'b0;
|
signal_single_pulse <= 1'b0;
|
||||||
|
|
||||||
signal_delay <= signal;
|
signal_delay <= signal;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,109 +1,109 @@
|
|||||||
module SampleDisplay(
|
module SampleDisplay(
|
||||||
output wire [6:0] display,
|
output wire [6:0] display,
|
||||||
output wire [3:0] digit,
|
output wire [3:0] digit,
|
||||||
inout wire PS2_DATA,
|
inout wire PS2_DATA,
|
||||||
inout wire PS2_CLK,
|
inout wire PS2_CLK,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
input wire clk
|
input wire clk
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter [8:0] LEFT_SHIFT_CODES = 9'b0_0001_0010;
|
parameter [8:0] LEFT_SHIFT_CODES = 9'b0_0001_0010;
|
||||||
parameter [8:0] RIGHT_SHIFT_CODES = 9'b0_0101_1001;
|
parameter [8:0] RIGHT_SHIFT_CODES = 9'b0_0101_1001;
|
||||||
parameter [8:0] KEY_CODES_00 = 9'b0_0100_0101; // 0 => 45
|
parameter [8:0] KEY_CODES_00 = 9'b0_0100_0101; // 0 => 45
|
||||||
parameter [8:0] KEY_CODES_01 = 9'b0_0001_0110; // 1 => 16
|
parameter [8:0] KEY_CODES_01 = 9'b0_0001_0110; // 1 => 16
|
||||||
parameter [8:0] KEY_CODES_02 = 9'b0_0001_1110; // 2 => 1E
|
parameter [8:0] KEY_CODES_02 = 9'b0_0001_1110; // 2 => 1E
|
||||||
parameter [8:0] KEY_CODES_03 = 9'b0_0010_0110; // 3 => 26
|
parameter [8:0] KEY_CODES_03 = 9'b0_0010_0110; // 3 => 26
|
||||||
parameter [8:0] KEY_CODES_04 = 9'b0_0010_0101; // 4 => 25
|
parameter [8:0] KEY_CODES_04 = 9'b0_0010_0101; // 4 => 25
|
||||||
parameter [8:0] KEY_CODES_05 = 9'b0_0010_1110; // 5 => 2E
|
parameter [8:0] KEY_CODES_05 = 9'b0_0010_1110; // 5 => 2E
|
||||||
parameter [8:0] KEY_CODES_06 = 9'b0_0011_0110; // 6 => 36
|
parameter [8:0] KEY_CODES_06 = 9'b0_0011_0110; // 6 => 36
|
||||||
parameter [8:0] KEY_CODES_07 = 9'b0_0011_1101; // 7 => 3D
|
parameter [8:0] KEY_CODES_07 = 9'b0_0011_1101; // 7 => 3D
|
||||||
parameter [8:0] KEY_CODES_08 = 9'b0_0011_1110; // 8 => 3E
|
parameter [8:0] KEY_CODES_08 = 9'b0_0011_1110; // 8 => 3E
|
||||||
parameter [8:0] KEY_CODES_09 = 9'b0_0100_0110; // 9 => 46
|
parameter [8:0] KEY_CODES_09 = 9'b0_0100_0110; // 9 => 46
|
||||||
|
|
||||||
parameter [8:0] KEY_CODES_10 = 9'b0_0111_0000; // right_0 => 70
|
parameter [8:0] KEY_CODES_10 = 9'b0_0111_0000; // right_0 => 70
|
||||||
parameter [8:0] KEY_CODES_11 = 9'b0_0110_1001; // right_1 => 69
|
parameter [8:0] KEY_CODES_11 = 9'b0_0110_1001; // right_1 => 69
|
||||||
parameter [8:0] KEY_CODES_12 = 9'b0_0111_0010; // right_2 => 72
|
parameter [8:0] KEY_CODES_12 = 9'b0_0111_0010; // right_2 => 72
|
||||||
parameter [8:0] KEY_CODES_13 = 9'b0_0111_1010; // right_3 => 7A
|
parameter [8:0] KEY_CODES_13 = 9'b0_0111_1010; // right_3 => 7A
|
||||||
parameter [8:0] KEY_CODES_14 = 9'b0_0110_1011; // right_4 => 6B
|
parameter [8:0] KEY_CODES_14 = 9'b0_0110_1011; // right_4 => 6B
|
||||||
parameter [8:0] KEY_CODES_15 = 9'b0_0111_0011; // right_5 => 73
|
parameter [8:0] KEY_CODES_15 = 9'b0_0111_0011; // right_5 => 73
|
||||||
parameter [8:0] KEY_CODES_16 = 9'b0_0111_0100; // right_6 => 74
|
parameter [8:0] KEY_CODES_16 = 9'b0_0111_0100; // right_6 => 74
|
||||||
parameter [8:0] KEY_CODES_17 = 9'b0_0110_1100; // right_7 => 6C
|
parameter [8:0] KEY_CODES_17 = 9'b0_0110_1100; // right_7 => 6C
|
||||||
parameter [8:0] KEY_CODES_18 = 9'b0_0111_0101; // right_8 => 75
|
parameter [8:0] KEY_CODES_18 = 9'b0_0111_0101; // right_8 => 75
|
||||||
parameter [8:0] KEY_CODES_19 = 9'b0_0111_1101; // right_9 => 7D
|
parameter [8:0] KEY_CODES_19 = 9'b0_0111_1101; // right_9 => 7D
|
||||||
|
|
||||||
reg [15:0] nums, next_nums;
|
reg [15:0] nums, next_nums;
|
||||||
reg [3:0] key_num;
|
reg [3:0] key_num;
|
||||||
reg [9:0] last_key;
|
reg [9:0] last_key;
|
||||||
|
|
||||||
wire shift_down;
|
wire shift_down;
|
||||||
wire [511:0] key_down;
|
wire [511:0] key_down;
|
||||||
wire [8:0] last_change;
|
wire [8:0] last_change;
|
||||||
wire been_ready;
|
wire been_ready;
|
||||||
|
|
||||||
assign shift_down = (key_down[LEFT_SHIFT_CODES] == 1'b1 || key_down[RIGHT_SHIFT_CODES] == 1'b1) ? 1'b1 : 1'b0;
|
assign shift_down = (key_down[LEFT_SHIFT_CODES] == 1'b1 || key_down[RIGHT_SHIFT_CODES] == 1'b1) ? 1'b1 : 1'b0;
|
||||||
|
|
||||||
SevenSegment seven_seg (
|
SevenSegment seven_seg (
|
||||||
.display(display),
|
.display(display),
|
||||||
.digit(digit),
|
.digit(digit),
|
||||||
.nums(nums),
|
.nums(nums),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
.clk(clk)
|
.clk(clk)
|
||||||
);
|
);
|
||||||
|
|
||||||
KeyboardDecoder key_de (
|
KeyboardDecoder key_de (
|
||||||
.key_down(key_down),
|
.key_down(key_down),
|
||||||
.last_change(last_change),
|
.last_change(last_change),
|
||||||
.key_valid(been_ready),
|
.key_valid(been_ready),
|
||||||
.PS2_DATA(PS2_DATA),
|
.PS2_DATA(PS2_DATA),
|
||||||
.PS2_CLK(PS2_CLK),
|
.PS2_CLK(PS2_CLK),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
.clk(clk)
|
.clk(clk)
|
||||||
);
|
);
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
nums <= 16'b0;
|
nums <= 16'b0;
|
||||||
end else begin
|
end else begin
|
||||||
nums <= next_nums;
|
nums <= next_nums;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
next_nums = nums;
|
next_nums = nums;
|
||||||
if (been_ready && key_down[last_change] == 1'b1) begin
|
if (been_ready && key_down[last_change] == 1'b1) begin
|
||||||
if (key_num != 4'b1111) begin
|
if (key_num != 4'b1111) begin
|
||||||
if (shift_down == 1'b1) begin
|
if (shift_down == 1'b1) begin
|
||||||
next_nums = {key_num, nums[15:4]};
|
next_nums = {key_num, nums[15:4]};
|
||||||
end else begin
|
end else begin
|
||||||
next_nums = {nums[11:0], key_num};
|
next_nums = {nums[11:0], key_num};
|
||||||
end
|
end
|
||||||
end else next_nums = next_nums;
|
end else next_nums = next_nums;
|
||||||
end else next_nums = next_nums;
|
end else next_nums = next_nums;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
case (last_change)
|
case (last_change)
|
||||||
KEY_CODES_00 : key_num = 4'b0000;
|
KEY_CODES_00 : key_num = 4'b0000;
|
||||||
KEY_CODES_01 : key_num = 4'b0001;
|
KEY_CODES_01 : key_num = 4'b0001;
|
||||||
KEY_CODES_02 : key_num = 4'b0010;
|
KEY_CODES_02 : key_num = 4'b0010;
|
||||||
KEY_CODES_03 : key_num = 4'b0011;
|
KEY_CODES_03 : key_num = 4'b0011;
|
||||||
KEY_CODES_04 : key_num = 4'b0100;
|
KEY_CODES_04 : key_num = 4'b0100;
|
||||||
KEY_CODES_05 : key_num = 4'b0101;
|
KEY_CODES_05 : key_num = 4'b0101;
|
||||||
KEY_CODES_06 : key_num = 4'b0110;
|
KEY_CODES_06 : key_num = 4'b0110;
|
||||||
KEY_CODES_07 : key_num = 4'b0111;
|
KEY_CODES_07 : key_num = 4'b0111;
|
||||||
KEY_CODES_08 : key_num = 4'b1000;
|
KEY_CODES_08 : key_num = 4'b1000;
|
||||||
KEY_CODES_09 : key_num = 4'b1001;
|
KEY_CODES_09 : key_num = 4'b1001;
|
||||||
KEY_CODES_10 : key_num = 4'b0000;
|
KEY_CODES_10 : key_num = 4'b0000;
|
||||||
KEY_CODES_11 : key_num = 4'b0001;
|
KEY_CODES_11 : key_num = 4'b0001;
|
||||||
KEY_CODES_12 : key_num = 4'b0010;
|
KEY_CODES_12 : key_num = 4'b0010;
|
||||||
KEY_CODES_13 : key_num = 4'b0011;
|
KEY_CODES_13 : key_num = 4'b0011;
|
||||||
KEY_CODES_14 : key_num = 4'b0100;
|
KEY_CODES_14 : key_num = 4'b0100;
|
||||||
KEY_CODES_15 : key_num = 4'b0101;
|
KEY_CODES_15 : key_num = 4'b0101;
|
||||||
KEY_CODES_16 : key_num = 4'b0110;
|
KEY_CODES_16 : key_num = 4'b0110;
|
||||||
KEY_CODES_17 : key_num = 4'b0111;
|
KEY_CODES_17 : key_num = 4'b0111;
|
||||||
KEY_CODES_18 : key_num = 4'b1000;
|
KEY_CODES_18 : key_num = 4'b1000;
|
||||||
KEY_CODES_19 : key_num = 4'b1001;
|
KEY_CODES_19 : key_num = 4'b1001;
|
||||||
default : key_num = 4'b1111;
|
default : key_num = 4'b1111;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,69 +1,69 @@
|
|||||||
module SevenSegment(
|
module SevenSegment(
|
||||||
output reg [6:0] display,
|
output reg [6:0] display,
|
||||||
output reg [3:0] digit,
|
output reg [3:0] digit,
|
||||||
input wire [15:0] nums,
|
input wire [15:0] nums,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
input wire clk
|
input wire clk
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [15:0] clk_divider;
|
reg [15:0] clk_divider;
|
||||||
reg [3:0] display_num;
|
reg [3:0] display_num;
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
clk_divider <= 16'b0;
|
clk_divider <= 16'b0;
|
||||||
end else begin
|
end else begin
|
||||||
clk_divider <= clk_divider + 16'b1;
|
clk_divider <= clk_divider + 16'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
display_num <= 4'b0000;
|
display_num <= 4'b0000;
|
||||||
digit <= 4'b1111;
|
digit <= 4'b1111;
|
||||||
end else if (clk_divider == {16{1'b1}}) begin
|
end else if (clk_divider == {16{1'b1}}) begin
|
||||||
case (digit)
|
case (digit)
|
||||||
4'b1110 : begin
|
4'b1110 : begin
|
||||||
display_num <= nums[7:4];
|
display_num <= nums[7:4];
|
||||||
digit <= 4'b1101;
|
digit <= 4'b1101;
|
||||||
end
|
end
|
||||||
4'b1101 : begin
|
4'b1101 : begin
|
||||||
display_num <= nums[11:8];
|
display_num <= nums[11:8];
|
||||||
digit <= 4'b1011;
|
digit <= 4'b1011;
|
||||||
end
|
end
|
||||||
4'b1011 : begin
|
4'b1011 : begin
|
||||||
display_num <= nums[15:12];
|
display_num <= nums[15:12];
|
||||||
digit <= 4'b0111;
|
digit <= 4'b0111;
|
||||||
end
|
end
|
||||||
4'b0111 : begin
|
4'b0111 : begin
|
||||||
display_num <= nums[3:0];
|
display_num <= nums[3:0];
|
||||||
digit <= 4'b1110;
|
digit <= 4'b1110;
|
||||||
end
|
end
|
||||||
default : begin
|
default : begin
|
||||||
display_num <= nums[3:0];
|
display_num <= nums[3:0];
|
||||||
digit <= 4'b1110;
|
digit <= 4'b1110;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
display_num <= display_num;
|
display_num <= display_num;
|
||||||
digit <= digit;
|
digit <= digit;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (*) begin
|
always @ (*) begin
|
||||||
case (display_num)
|
case (display_num)
|
||||||
0 : display = 7'b1000000; //0000
|
0 : display = 7'b1000000; //0000
|
||||||
1 : display = 7'b1111001; //0001
|
1 : display = 7'b1111001; //0001
|
||||||
2 : display = 7'b0100100; //0010
|
2 : display = 7'b0100100; //0010
|
||||||
3 : display = 7'b0110000; //0011
|
3 : display = 7'b0110000; //0011
|
||||||
4 : display = 7'b0011001; //0100
|
4 : display = 7'b0011001; //0100
|
||||||
5 : display = 7'b0010010; //0101
|
5 : display = 7'b0010010; //0101
|
||||||
6 : display = 7'b0000010; //0110
|
6 : display = 7'b0000010; //0110
|
||||||
7 : display = 7'b1111000; //0111
|
7 : display = 7'b1111000; //0111
|
||||||
8 : display = 7'b0000000; //1000
|
8 : display = 7'b0000000; //1000
|
||||||
9 : display = 7'b0010000; //1001
|
9 : display = 7'b0010000; //1001
|
||||||
default : display = 7'b1111111;
|
default : display = 7'b1111111;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -4,7 +4,7 @@ module KeyboardCtrl#(
|
|||||||
output reg [7:0] key_in,
|
output reg [7:0] key_in,
|
||||||
output reg is_extend,
|
output reg is_extend,
|
||||||
output reg is_break,
|
output reg is_break,
|
||||||
output reg valid,
|
output reg valid,
|
||||||
output err,
|
output err,
|
||||||
inout PS2_DATA,
|
inout PS2_DATA,
|
||||||
inout PS2_CLK,
|
inout PS2_CLK,
|
||||||
@ -16,17 +16,17 @@ module KeyboardCtrl#(
|
|||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
|
|
||||||
parameter RESET = 3'd0;
|
parameter RESET = 3'd0;
|
||||||
parameter SEND_CMD = 3'd1;
|
parameter SEND_CMD = 3'd1;
|
||||||
parameter WAIT_ACK = 3'd2;
|
parameter WAIT_ACK = 3'd2;
|
||||||
parameter WAIT_KEYIN = 3'd3;
|
parameter WAIT_KEYIN = 3'd3;
|
||||||
parameter GET_BREAK = 3'd4;
|
parameter GET_BREAK = 3'd4;
|
||||||
parameter GET_EXTEND = 3'd5;
|
parameter GET_EXTEND = 3'd5;
|
||||||
parameter RESET_WAIT_BAT = 3'd6;
|
parameter RESET_WAIT_BAT = 3'd6;
|
||||||
|
|
||||||
parameter CMD_RESET = 8'hFF;
|
parameter CMD_RESET = 8'hFF;
|
||||||
parameter CMD_SET_STATUS_LEDS = 8'hED;
|
parameter CMD_SET_STATUS_LEDS = 8'hED;
|
||||||
parameter RSP_ACK = 8'hFA;
|
parameter RSP_ACK = 8'hFA;
|
||||||
parameter RSP_BAT_PASS = 8'hAA;
|
parameter RSP_BAT_PASS = 8'hAA;
|
||||||
|
|
||||||
parameter BREAK_CODE = 8'hF0;
|
parameter BREAK_CODE = 8'hF0;
|
||||||
parameter EXTEND_CODE = 8'hE0;
|
parameter EXTEND_CODE = 8'hE0;
|
||||||
@ -35,138 +35,138 @@ module KeyboardCtrl#(
|
|||||||
parameter SCR_LOCK = 8'h7E;
|
parameter SCR_LOCK = 8'h7E;
|
||||||
|
|
||||||
wire [7:0] rx_data;
|
wire [7:0] rx_data;
|
||||||
wire rx_valid;
|
wire rx_valid;
|
||||||
wire busy;
|
wire busy;
|
||||||
|
|
||||||
reg [7:0] tx_data;
|
reg [7:0] tx_data;
|
||||||
reg tx_valid;
|
reg tx_valid;
|
||||||
reg [2:0] state;
|
reg [2:0] state;
|
||||||
reg [2:0] lock_status;
|
reg [2:0] lock_status;
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst)
|
always @ (posedge clk, posedge rst)
|
||||||
if(rst)
|
if(rst)
|
||||||
key_in <= 0;
|
key_in <= 0;
|
||||||
else if(rx_valid)
|
else if(rx_valid)
|
||||||
key_in <= rx_data;
|
key_in <= rx_data;
|
||||||
else
|
else
|
||||||
key_in <= key_in;
|
key_in <= key_in;
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst)begin
|
always @ (posedge clk, posedge rst)begin
|
||||||
if(rst)begin
|
if(rst)begin
|
||||||
state <= RESET;
|
state <= RESET;
|
||||||
is_extend <= 1'b0;
|
is_extend <= 1'b0;
|
||||||
is_break <= 1'b1;
|
is_break <= 1'b1;
|
||||||
valid <= 1'b0;
|
valid <= 1'b0;
|
||||||
lock_status <= 3'b0;
|
lock_status <= 3'b0;
|
||||||
tx_data <= 8'h00;
|
tx_data <= 8'h00;
|
||||||
tx_valid <= 1'b0;
|
tx_valid <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
is_extend <= 1'b0;
|
is_extend <= 1'b0;
|
||||||
is_break <= 1'b0;
|
is_break <= 1'b0;
|
||||||
valid <= 1'b0;
|
valid <= 1'b0;
|
||||||
lock_status <= lock_status;
|
lock_status <= lock_status;
|
||||||
tx_data <= tx_data;
|
tx_data <= tx_data;
|
||||||
tx_valid <= 1'b0;
|
tx_valid <= 1'b0;
|
||||||
case(state)
|
case(state)
|
||||||
RESET:begin
|
RESET:begin
|
||||||
is_extend <= 1'b0;
|
is_extend <= 1'b0;
|
||||||
is_break <= 1'b1;
|
is_break <= 1'b1;
|
||||||
valid <= 1'b0;
|
valid <= 1'b0;
|
||||||
lock_status <= 3'b0;
|
lock_status <= 3'b0;
|
||||||
tx_data <= CMD_RESET;
|
tx_data <= CMD_RESET;
|
||||||
tx_valid <= 1'b0;
|
tx_valid <= 1'b0;
|
||||||
state <= SEND_CMD;
|
state <= SEND_CMD;
|
||||||
end
|
end
|
||||||
|
|
||||||
SEND_CMD:begin
|
SEND_CMD:begin
|
||||||
if(busy == 1'b0)begin
|
if(busy == 1'b0)begin
|
||||||
tx_valid <= 1'b1;
|
tx_valid <= 1'b1;
|
||||||
state <= WAIT_ACK;
|
state <= WAIT_ACK;
|
||||||
end else begin
|
end else begin
|
||||||
tx_valid <= 1'b0;
|
tx_valid <= 1'b0;
|
||||||
state <= SEND_CMD;
|
state <= SEND_CMD;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
WAIT_ACK:begin
|
WAIT_ACK:begin
|
||||||
if(rx_valid == 1'b1)begin
|
if(rx_valid == 1'b1)begin
|
||||||
if(rx_data == RSP_ACK && tx_data == CMD_RESET)begin
|
if(rx_data == RSP_ACK && tx_data == CMD_RESET)begin
|
||||||
state <= RESET_WAIT_BAT;
|
state <= RESET_WAIT_BAT;
|
||||||
end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS)begin
|
end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS)begin
|
||||||
tx_data <= {5'b00000, lock_status};
|
tx_data <= {5'b00000, lock_status};
|
||||||
state <= SEND_CMD;
|
state <= SEND_CMD;
|
||||||
end else begin
|
end else begin
|
||||||
state <= WAIT_KEYIN;
|
state <= WAIT_KEYIN;
|
||||||
end
|
end
|
||||||
end else if(err == 1'b1)begin
|
end else if(err == 1'b1)begin
|
||||||
state <= RESET;
|
state <= RESET;
|
||||||
end else begin
|
end else begin
|
||||||
state <= WAIT_ACK;
|
state <= WAIT_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
WAIT_KEYIN:begin
|
WAIT_KEYIN:begin
|
||||||
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
|
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
|
||||||
state <= GET_BREAK;
|
state <= GET_BREAK;
|
||||||
end else if(rx_valid == 1'b1 && rx_data == EXTEND_CODE)begin
|
end else if(rx_valid == 1'b1 && rx_data == EXTEND_CODE)begin
|
||||||
state <= GET_EXTEND;
|
state <= GET_EXTEND;
|
||||||
end else if(rx_valid == 1'b1)begin
|
end else if(rx_valid == 1'b1)begin
|
||||||
state <= WAIT_KEYIN;
|
state <= WAIT_KEYIN;
|
||||||
valid <= 1'b1;
|
|
||||||
end else if(err == 1'b1)begin
|
|
||||||
state <= RESET;
|
|
||||||
end else begin
|
|
||||||
state <= WAIT_KEYIN;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
GET_BREAK:begin
|
|
||||||
is_extend <= is_extend;
|
|
||||||
if(rx_valid == 1'b1)begin
|
|
||||||
state <= WAIT_KEYIN;
|
|
||||||
valid <= 1'b1;
|
valid <= 1'b1;
|
||||||
is_break <= 1'b1;
|
end else if(err == 1'b1)begin
|
||||||
end else if(err == 1'b1)begin
|
state <= RESET;
|
||||||
state <= RESET;
|
end else begin
|
||||||
end else begin
|
state <= WAIT_KEYIN;
|
||||||
state <= GET_BREAK;
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
GET_BREAK:begin
|
||||||
GET_EXTEND:begin
|
is_extend <= is_extend;
|
||||||
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
|
if(rx_valid == 1'b1)begin
|
||||||
state <= GET_BREAK;
|
state <= WAIT_KEYIN;
|
||||||
is_extend <= 1'b1;
|
|
||||||
end else if(rx_valid == 1'b1)begin
|
|
||||||
state <= WAIT_KEYIN;
|
|
||||||
valid <= 1'b1;
|
valid <= 1'b1;
|
||||||
is_extend <= 1'b1;
|
is_break <= 1'b1;
|
||||||
end else if(err == 1'b1)begin
|
end else if(err == 1'b1)begin
|
||||||
state <= RESET;
|
state <= RESET;
|
||||||
end else begin
|
end else begin
|
||||||
state <= GET_EXTEND;
|
state <= GET_BREAK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RESET_WAIT_BAT:begin
|
GET_EXTEND:begin
|
||||||
if(rx_valid == 1'b1 && rx_data == RSP_BAT_PASS)begin
|
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
|
||||||
state <= WAIT_KEYIN;
|
state <= GET_BREAK;
|
||||||
end else if(rx_valid == 1'b1)begin
|
is_extend <= 1'b1;
|
||||||
state <= RESET;
|
end else if(rx_valid == 1'b1)begin
|
||||||
end else if(err == 1'b1)begin
|
state <= WAIT_KEYIN;
|
||||||
state <= RESET;
|
valid <= 1'b1;
|
||||||
end else begin
|
is_extend <= 1'b1;
|
||||||
state <= RESET_WAIT_BAT;
|
end else if(err == 1'b1)begin
|
||||||
end
|
state <= RESET;
|
||||||
end
|
end else begin
|
||||||
default:begin
|
state <= GET_EXTEND;
|
||||||
state <= RESET;
|
end
|
||||||
valid <= 1'b0;
|
end
|
||||||
end
|
|
||||||
endcase
|
RESET_WAIT_BAT:begin
|
||||||
end
|
if(rx_valid == 1'b1 && rx_data == RSP_BAT_PASS)begin
|
||||||
end
|
state <= WAIT_KEYIN;
|
||||||
|
end else if(rx_valid == 1'b1)begin
|
||||||
|
state <= RESET;
|
||||||
|
end else if(err == 1'b1)begin
|
||||||
|
state <= RESET;
|
||||||
|
end else begin
|
||||||
|
state <= RESET_WAIT_BAT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default:begin
|
||||||
|
state <= RESET;
|
||||||
|
valid <= 1'b0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Ps2Interface #(
|
Ps2Interface #(
|
||||||
.SYSCLK_FREQUENCY_HZ(SYSCLK_FREQUENCY_HZ)
|
.SYSCLK_FREQUENCY_HZ(SYSCLK_FREQUENCY_HZ)
|
||||||
) Ps2Interface_i(
|
) Ps2Interface_i(
|
||||||
|
@ -268,7 +268,7 @@ module Ps2Interface#(
|
|||||||
.I(ps2_clk_out),
|
.I(ps2_clk_out),
|
||||||
.T(~ps2_clk_en)
|
.T(~ps2_clk_en)
|
||||||
);
|
);
|
||||||
|
|
||||||
IOBUF IOBUF_inst_1(
|
IOBUF IOBUF_inst_1(
|
||||||
.O(ps2_data_in),
|
.O(ps2_data_in),
|
||||||
.IO(ps2_data),
|
.IO(ps2_data),
|
||||||
@ -281,15 +281,15 @@ module Ps2Interface#(
|
|||||||
|
|
||||||
always @ (posedge clk, posedge rst)begin
|
always @ (posedge clk, posedge rst)begin
|
||||||
if(rst)begin
|
if(rst)begin
|
||||||
rx_data <= 0;
|
rx_data <= 0;
|
||||||
rx_valid <= 1'b0;
|
rx_valid <= 1'b0;
|
||||||
end else if(rx_finish==1'b1)begin // set read signal for the client to know
|
end else if(rx_finish==1'b1)begin // set read signal for the client to know
|
||||||
rx_data <= frame[8:1]; // a new byte was received and is available on rx_data
|
rx_data <= frame[8:1]; // a new byte was received and is available on rx_data
|
||||||
rx_valid <= 1'b1;
|
rx_valid <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
rx_data <= rx_data;
|
rx_data <= rx_data;
|
||||||
rx_valid <= 1'b0;
|
rx_valid <= 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign rx_parity = parity_table[frame[8:1]];
|
assign rx_parity = parity_table[frame[8:1]];
|
||||||
@ -297,266 +297,266 @@ module Ps2Interface#(
|
|||||||
|
|
||||||
always @ (posedge clk, posedge rst)begin
|
always @ (posedge clk, posedge rst)begin
|
||||||
if(rst)
|
if(rst)
|
||||||
frame <= 0;
|
frame <= 0;
|
||||||
else if(tx_valid==1'b1 && state==IDLE) begin
|
else if(tx_valid==1'b1 && state==IDLE) begin
|
||||||
frame[0] <= 1'b0; //start bit
|
frame[0] <= 1'b0; //start bit
|
||||||
frame[8:1] <= tx_data; //data
|
frame[8:1] <= tx_data; //data
|
||||||
frame[9] <= tx_parity; //parity bit
|
frame[9] <= tx_parity; //parity bit
|
||||||
frame[10] <= 1'b1; //stop bit
|
frame[10] <= 1'b1; //stop bit
|
||||||
end else if(state==RX_NEG_EDGE || state==TX_CLK_LOW)
|
end else if(state==RX_NEG_EDGE || state==TX_CLK_LOW)
|
||||||
frame <= {ps2_data_s, frame[10:1]};
|
frame <= {ps2_data_s, frame[10:1]};
|
||||||
else
|
else
|
||||||
frame <= frame;
|
frame <= frame;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Debouncer
|
// Debouncer
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if(rst)begin
|
if(rst)begin
|
||||||
ps2_clk_s <= 1'b1;
|
ps2_clk_s <= 1'b1;
|
||||||
clk_inter <= 1'b1;
|
clk_inter <= 1'b1;
|
||||||
clk_count <= 0;
|
clk_count <= 0;
|
||||||
end else if(ps2_clk_in != clk_inter)begin
|
end else if(ps2_clk_in != clk_inter)begin
|
||||||
ps2_clk_s <= ps2_clk_s;
|
ps2_clk_s <= ps2_clk_s;
|
||||||
clk_inter <= ps2_clk_in;
|
clk_inter <= ps2_clk_in;
|
||||||
clk_count <= 0;
|
clk_count <= 0;
|
||||||
end else if(clk_count == DEBOUNCE_DELAY) begin
|
end else if(clk_count == DEBOUNCE_DELAY) begin
|
||||||
ps2_clk_s <= clk_inter;
|
ps2_clk_s <= clk_inter;
|
||||||
clk_inter <= clk_inter;
|
clk_inter <= clk_inter;
|
||||||
clk_count <= clk_count;
|
clk_count <= clk_count;
|
||||||
end else begin
|
end else begin
|
||||||
ps2_clk_s <= ps2_clk_s;
|
ps2_clk_s <= ps2_clk_s;
|
||||||
clk_inter <= clk_inter;
|
clk_inter <= clk_inter;
|
||||||
clk_count <= clk_count + 1'b1;
|
clk_count <= clk_count + 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst) begin
|
always @ (posedge clk, posedge rst) begin
|
||||||
if(rst)begin
|
if(rst)begin
|
||||||
ps2_data_s <= 1'b1;
|
ps2_data_s <= 1'b1;
|
||||||
data_inter <= 1'b1;
|
data_inter <= 1'b1;
|
||||||
data_count <= 0;
|
data_count <= 0;
|
||||||
end else if(ps2_data_in != data_inter)begin
|
end else if(ps2_data_in != data_inter)begin
|
||||||
ps2_data_s <= ps2_data_s;
|
ps2_data_s <= ps2_data_s;
|
||||||
data_inter <= ps2_data_in;
|
data_inter <= ps2_data_in;
|
||||||
data_count <= 0;
|
data_count <= 0;
|
||||||
end else if(data_count == DEBOUNCE_DELAY) begin
|
end else if(data_count == DEBOUNCE_DELAY) begin
|
||||||
ps2_data_s <= data_inter;
|
ps2_data_s <= data_inter;
|
||||||
data_inter <= data_inter;
|
data_inter <= data_inter;
|
||||||
data_count <= data_count;
|
data_count <= data_count;
|
||||||
end else begin
|
end else begin
|
||||||
ps2_data_s <= ps2_data_s;
|
ps2_data_s <= ps2_data_s;
|
||||||
data_inter <= data_inter;
|
data_inter <= data_inter;
|
||||||
data_count <= data_count + 1'b1;
|
data_count <= data_count + 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// FSM
|
// FSM
|
||||||
always @ (posedge clk, posedge rst)begin
|
always @ (posedge clk, posedge rst)begin
|
||||||
if(rst)begin
|
if(rst)begin
|
||||||
state <= IDLE;
|
state <= IDLE;
|
||||||
ps2_clk_en <= 1'b0;
|
ps2_clk_en <= 1'b0;
|
||||||
ps2_clk_out <= 1'b0;
|
ps2_clk_out <= 1'b0;
|
||||||
ps2_data_en <= 1'b0;
|
ps2_data_en <= 1'b0;
|
||||||
ps2_data_out <= 1'b0;
|
ps2_data_out <= 1'b0;
|
||||||
err <= 1'b0;
|
err <= 1'b0;
|
||||||
counter <= 0;
|
counter <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
state <= state_next;
|
state <= state_next;
|
||||||
ps2_clk_en <= ps2_clk_en_next;
|
ps2_clk_en <= ps2_clk_en_next;
|
||||||
ps2_clk_out <= ps2_clk_out_next;
|
ps2_clk_out <= ps2_clk_out_next;
|
||||||
ps2_data_en <= ps2_data_en_next;
|
ps2_data_en <= ps2_data_en_next;
|
||||||
ps2_data_out <= ps2_data_out_next;
|
ps2_data_out <= ps2_data_out_next;
|
||||||
err <= err_next;
|
err <= err_next;
|
||||||
counter <= counter_next;
|
counter <= counter_next;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ * begin
|
always @ * begin
|
||||||
state_next = IDLE; // default values for these signals
|
state_next = IDLE; // default values for these signals
|
||||||
ps2_clk_en_next = 1'b0; // ensures signals are reset to default value
|
ps2_clk_en_next = 1'b0; // ensures signals are reset to default value
|
||||||
ps2_clk_out_next = 1'b1; // when conditions for their activation are no
|
ps2_clk_out_next = 1'b1; // when conditions for their activation are no
|
||||||
ps2_data_en_next = 1'b0; // longer applied (transition to other state,
|
ps2_data_en_next = 1'b0; // longer applied (transition to other state,
|
||||||
ps2_data_out_next = 1'b1; // where signal should not be active)
|
ps2_data_out_next = 1'b1; // where signal should not be active)
|
||||||
err_next = 1'b0; // Idle value for ps2_clk and ps2_data is 'Z'
|
err_next = 1'b0; // Idle value for ps2_clk and ps2_data is 'Z'
|
||||||
rx_finish = 1'b0;
|
rx_finish = 1'b0;
|
||||||
counter_next = 0;
|
counter_next = 0;
|
||||||
case(state)
|
case(state)
|
||||||
IDLE:begin // wait for the device to begin a transmission
|
IDLE:begin // wait for the device to begin a transmission
|
||||||
if(tx_valid == 1'b1)begin // by pulling the clock line low and go to state
|
if(tx_valid == 1'b1)begin // by pulling the clock line low and go to state
|
||||||
state_next = TX_FORCE_CLK_LOW; // RX_NEG_EDGE or, if write is high, the
|
state_next = TX_FORCE_CLK_LOW; // RX_NEG_EDGE or, if write is high, the
|
||||||
end else if(ps2_clk_s == 1'b0)begin // client of this interface wants to send a byte
|
end else if(ps2_clk_s == 1'b0)begin // client of this interface wants to send a byte
|
||||||
state_next = RX_NEG_EDGE; // to the device and a transition is made to state
|
state_next = RX_NEG_EDGE; // to the device and a transition is made to state
|
||||||
end else begin // TX_FORCE_CLK_LOW
|
end else begin // TX_FORCE_CLK_LOW
|
||||||
state_next = IDLE;
|
state_next = IDLE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RX_NEG_EDGE:begin // data must be read into frame in this state
|
RX_NEG_EDGE:begin // data must be read into frame in this state
|
||||||
state_next = RX_CLK_LOW; // the ps2_clk just transitioned from high to low
|
state_next = RX_CLK_LOW; // the ps2_clk just transitioned from high to low
|
||||||
end
|
end
|
||||||
|
|
||||||
RX_CLK_LOW:begin // ps2_clk line is low, wait for it to go high
|
RX_CLK_LOW:begin // ps2_clk line is low, wait for it to go high
|
||||||
if(ps2_clk_s == 1'b1)begin
|
if(ps2_clk_s == 1'b1)begin
|
||||||
state_next = RX_CLK_HIGH;
|
state_next = RX_CLK_HIGH;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = RX_CLK_LOW;
|
state_next = RX_CLK_LOW;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RX_CLK_HIGH:begin // ps2_clk is high, check if all the bits have been read
|
RX_CLK_HIGH:begin // ps2_clk is high, check if all the bits have been read
|
||||||
if(bits_count == BITS_NUM)begin // if, last bit read, check parity, and if parity ok
|
if(bits_count == BITS_NUM)begin // if, last bit read, check parity, and if parity ok
|
||||||
if(rx_parity != frame[9])begin // load received data into rx_data.
|
if(rx_parity != frame[9])begin // load received data into rx_data.
|
||||||
err_next = 1'b1; // else if more bits left, then wait for the ps2_clk to
|
err_next = 1'b1; // else if more bits left, then wait for the ps2_clk to
|
||||||
state_next = IDLE; // go low
|
state_next = IDLE; // go low
|
||||||
end else begin
|
end else begin
|
||||||
rx_finish = 1'b1;
|
rx_finish = 1'b1;
|
||||||
state_next = IDLE;
|
state_next = IDLE;
|
||||||
end
|
end
|
||||||
end else if(ps2_clk_s == 1'b0)begin
|
end else if(ps2_clk_s == 1'b0)begin
|
||||||
state_next = RX_NEG_EDGE;
|
state_next = RX_NEG_EDGE;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = RX_CLK_HIGH;
|
state_next = RX_CLK_HIGH;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_FORCE_CLK_LOW:begin // the client wishes to transmit a byte to the device
|
TX_FORCE_CLK_LOW:begin // the client wishes to transmit a byte to the device
|
||||||
ps2_clk_en_next = 1'b1; // this is done by holding ps2_clk down for at least 100us
|
ps2_clk_en_next = 1'b1; // this is done by holding ps2_clk down for at least 100us
|
||||||
ps2_clk_out_next = 1'b0; // bringing down ps2_data, wait 20us and then releasing
|
ps2_clk_out_next = 1'b0; // bringing down ps2_data, wait 20us and then releasing
|
||||||
if(counter == CLOCK_CNT_100US)begin // the ps2_clk.
|
if(counter == CLOCK_CNT_100US)begin // the ps2_clk.
|
||||||
state_next = TX_BRING_DATA_LOW; // This constitutes a request to send command.
|
state_next = TX_BRING_DATA_LOW; // This constitutes a request to send command.
|
||||||
counter_next = 0; // In this state, the ps2_clk line is held down and
|
counter_next = 0; // In this state, the ps2_clk line is held down and
|
||||||
end else begin // the counter for waiting 100us is enabled.
|
end else begin // the counter for waiting 100us is enabled.
|
||||||
state_next = TX_FORCE_CLK_LOW; // when the counter reached upper limit, transition
|
state_next = TX_FORCE_CLK_LOW; // when the counter reached upper limit, transition
|
||||||
counter_next = counter + 1'b1; // to TX_BRING_DATA_LOW
|
counter_next = counter + 1'b1; // to TX_BRING_DATA_LOW
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_BRING_DATA_LOW:begin // with the ps2_clk line low bring ps2_data low
|
TX_BRING_DATA_LOW:begin // with the ps2_clk line low bring ps2_data low
|
||||||
ps2_clk_en_next = 1'b1; // wait for 20us and then go to TX_RELEASE_CLK
|
ps2_clk_en_next = 1'b1; // wait for 20us and then go to TX_RELEASE_CLK
|
||||||
ps2_clk_out_next = 1'b0;
|
ps2_clk_out_next = 1'b0;
|
||||||
|
|
||||||
// set data line low
|
// set data line low
|
||||||
// when clock is released in the next state
|
// when clock is released in the next state
|
||||||
// the device will read bit 0 on data line
|
// the device will read bit 0 on data line
|
||||||
// and this bit represents the start bit.
|
// and this bit represents the start bit.
|
||||||
ps2_data_en_next = 1'b1;
|
ps2_data_en_next = 1'b1;
|
||||||
ps2_data_out_next = 1'b0;
|
ps2_data_out_next = 1'b0;
|
||||||
if(counter == CLOCK_CNT_20US)begin
|
if(counter == CLOCK_CNT_20US)begin
|
||||||
state_next = TX_RELEASE_CLK;
|
state_next = TX_RELEASE_CLK;
|
||||||
counter_next = 0;
|
counter_next = 0;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_BRING_DATA_LOW;
|
state_next = TX_BRING_DATA_LOW;
|
||||||
counter_next = counter + 1'b1;
|
counter_next = counter + 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_RELEASE_CLK:begin // release the ps2_clk line
|
TX_RELEASE_CLK:begin // release the ps2_clk line
|
||||||
ps2_clk_en_next = 1'b0; // keep holding data line low
|
ps2_clk_en_next = 1'b0; // keep holding data line low
|
||||||
ps2_data_en_next = 1'b1;
|
ps2_data_en_next = 1'b1;
|
||||||
ps2_data_out_next = 1'b0;
|
ps2_data_out_next = 1'b0;
|
||||||
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_WAIT_FIRTS_NEG_EDGE:begin // state is necessary because the clock signal
|
TX_WAIT_FIRTS_NEG_EDGE:begin // state is necessary because the clock signal
|
||||||
ps2_data_en_next = 1'b1; // is not released instantaneously and, because of debounce,
|
ps2_data_en_next = 1'b1; // is not released instantaneously and, because of debounce,
|
||||||
ps2_data_out_next = 1'b0; // delay is even greater.
|
ps2_data_out_next = 1'b0; // delay is even greater.
|
||||||
if(counter == 14'd63)begin // Wait 63 clock periods for the clock line to release
|
if(counter == 14'd63)begin // Wait 63 clock periods for the clock line to release
|
||||||
if(ps2_clk_s == 1'b0)begin // then if clock is low then go to tx_clk_l
|
if(ps2_clk_s == 1'b0)begin // then if clock is low then go to tx_clk_l
|
||||||
state_next = TX_CLK_LOW; // else wait until ps2_clk goes low.
|
state_next = TX_CLK_LOW; // else wait until ps2_clk goes low.
|
||||||
counter_next = 0;
|
counter_next = 0;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
||||||
counter_next = counter;
|
counter_next = counter;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
state_next = TX_WAIT_FIRTS_NEG_EDGE;
|
||||||
counter_next = counter + 1'b1;
|
counter_next = counter + 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_CLK_LOW:begin // place the least significant bit from frame
|
TX_CLK_LOW:begin // place the least significant bit from frame
|
||||||
ps2_data_en_next = 1'b1; // on the data line
|
ps2_data_en_next = 1'b1; // on the data line
|
||||||
ps2_data_out_next = frame[0]; // During this state the frame is shifted one
|
ps2_data_out_next = frame[0]; // During this state the frame is shifted one
|
||||||
state_next = TX_WAIT_POS_EDGE; // bit to the right
|
state_next = TX_WAIT_POS_EDGE; // bit to the right
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_WAIT_POS_EDGE:begin // wait for the clock to go high
|
TX_WAIT_POS_EDGE:begin // wait for the clock to go high
|
||||||
ps2_data_en_next = 1'b1; // this is the edge on which the device reads the data
|
ps2_data_en_next = 1'b1; // this is the edge on which the device reads the data
|
||||||
ps2_data_out_next = frame[0]; // on ps2_data.
|
ps2_data_out_next = frame[0]; // on ps2_data.
|
||||||
if(bits_count == BITS_NUM-1)begin // keep holding ps2_data on frame(0) because else
|
if(bits_count == BITS_NUM-1)begin // keep holding ps2_data on frame(0) because else
|
||||||
ps2_data_en_next = 1'b0; // will be released by default value.
|
ps2_data_en_next = 1'b0; // will be released by default value.
|
||||||
state_next = TX_WAIT_POS_EDGE_BEFORE_ACK; // Check if sent the last bit and if so, release data line
|
state_next = TX_WAIT_POS_EDGE_BEFORE_ACK; // Check if sent the last bit and if so, release data line
|
||||||
end else if(ps2_clk_s == 1'b1)begin // and go to state that wait for acknowledge
|
end else if(ps2_clk_s == 1'b1)begin // and go to state that wait for acknowledge
|
||||||
state_next = TX_CLK_HIGH;
|
state_next = TX_CLK_HIGH;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_WAIT_POS_EDGE;
|
state_next = TX_WAIT_POS_EDGE;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_CLK_HIGH:begin // ps2_clk is released, wait for down edge
|
TX_CLK_HIGH:begin // ps2_clk is released, wait for down edge
|
||||||
ps2_data_en_next = 1'b1; // and go to tx_clk_l when arrived
|
ps2_data_en_next = 1'b1; // and go to tx_clk_l when arrived
|
||||||
ps2_data_out_next = frame[0];
|
ps2_data_out_next = frame[0];
|
||||||
if(ps2_clk_s == 1'b0)begin
|
if(ps2_clk_s == 1'b0)begin
|
||||||
state_next = TX_CLK_LOW;
|
state_next = TX_CLK_LOW;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_CLK_HIGH;
|
state_next = TX_CLK_HIGH;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_WAIT_POS_EDGE_BEFORE_ACK:begin // release ps2_data and wait for rising edge of ps2_clk
|
TX_WAIT_POS_EDGE_BEFORE_ACK:begin // release ps2_data and wait for rising edge of ps2_clk
|
||||||
if(ps2_clk_s == 1'b1)begin // once this occurs, transition to tx_wait_ack
|
if(ps2_clk_s == 1'b1)begin // once this occurs, transition to tx_wait_ack
|
||||||
state_next = TX_WAIT_ACK;
|
state_next = TX_WAIT_ACK;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_WAIT_POS_EDGE_BEFORE_ACK;
|
state_next = TX_WAIT_POS_EDGE_BEFORE_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_WAIT_ACK:begin // wait for the falling edge of the clock line
|
TX_WAIT_ACK:begin // wait for the falling edge of the clock line
|
||||||
if(ps2_clk_s == 1'b0)begin // if data line is low when this occurs, the
|
if(ps2_clk_s == 1'b0)begin // if data line is low when this occurs, the
|
||||||
if(ps2_data_s == 1'b0) begin // ack is received
|
if(ps2_data_s == 1'b0) begin // ack is received
|
||||||
state_next = TX_RECEIVED_ACK; // else if data line is high, the device did not
|
state_next = TX_RECEIVED_ACK; // else if data line is high, the device did not
|
||||||
end else begin // acknowledge the transimission
|
end else begin // acknowledge the transimission
|
||||||
state_next = TX_ERROR_NO_ACK;
|
state_next = TX_ERROR_NO_ACK;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_WAIT_ACK;
|
state_next = TX_WAIT_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_RECEIVED_ACK:begin // wait for ps2_clk to be released together with ps2_data
|
TX_RECEIVED_ACK:begin // wait for ps2_clk to be released together with ps2_data
|
||||||
if(ps2_clk_s == 1'b1 && ps2_clk_s == 1'b1)begin // (bus to be idle) and go back to idle state
|
if(ps2_clk_s == 1'b1 && ps2_clk_s == 1'b1)begin // (bus to be idle) and go back to idle state
|
||||||
state_next = IDLE;
|
state_next = IDLE;
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_RECEIVED_ACK;
|
state_next = TX_RECEIVED_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
TX_ERROR_NO_ACK:begin
|
TX_ERROR_NO_ACK:begin
|
||||||
if(ps2_clk_s == 1'b1 && ps2_clk_s == 1'b1)begin // wait for ps2_clk to be released together with ps2_data
|
if(ps2_clk_s == 1'b1 && ps2_clk_s == 1'b1)begin // wait for ps2_clk to be released together with ps2_data
|
||||||
err_next = 1'b1; // (bus to be idle) and go back to idle state
|
err_next = 1'b1; // (bus to be idle) and go back to idle state
|
||||||
state_next = IDLE; // signal error for not receiving ack
|
state_next = IDLE; // signal error for not receiving ack
|
||||||
end else begin
|
end else begin
|
||||||
state_next = TX_ERROR_NO_ACK;
|
state_next = TX_ERROR_NO_ACK;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
default:begin // if invalid transition occurred, signal error and
|
default:begin // if invalid transition occurred, signal error and
|
||||||
err_next = 1'b1; // go back to idle state
|
err_next = 1'b1; // go back to idle state
|
||||||
state_next = IDLE;
|
state_next = IDLE;
|
||||||
end
|
end
|
||||||
|
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
always @ (posedge clk, posedge rst)begin
|
always @ (posedge clk, posedge rst)begin
|
||||||
if(rst)
|
if(rst)
|
||||||
bits_count <= 0;
|
bits_count <= 0;
|
||||||
else if(state==IDLE)
|
else if(state==IDLE)
|
||||||
bits_count <= 0;
|
bits_count <= 0;
|
||||||
else if(state==RX_NEG_EDGE || state==TX_CLK_LOW)
|
else if(state==RX_NEG_EDGE || state==TX_CLK_LOW)
|
||||||
bits_count <= bits_count + 1'b1;
|
bits_count <= bits_count + 1'b1;
|
||||||
else
|
else
|
||||||
bits_count <= bits_count;
|
bits_count <= bits_count;
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
x
Reference in New Issue
Block a user