Spartan6 FPGA 上的 4X4 键盘
4X4 Keypad on a Spartan6 FPGA
我已经坚持了一段时间。
对于我的项目,我正在尝试使用键盘输入制作数字锁。
我有一个 4X4 键盘,但我只使用了其中的 3 列。
目前,我只是想让键盘正常工作。
当我编译它时,我的默认情况下有效,但当我按下任何按钮时都不会改变。
`timescale 1ns / 1ps
module KeypadShit(input M_CLOCK, // FPGA clock
input ROW1, ROW2, ROW3, ROW4, COL1, COL2, COL3,
output [3:0] IO_SSEGD, // IO Board Seven Segment Digits
output reg [7:0] IO_SSEG, // 7=dp, 6=g, 5=f,4=e, 3=d,2=c,1=b, 0=a
output IO_SSEG_COL); // Seven segment column
assign IO_SSEGD = 4'b0111;
assign IO_SSEG_COL = 1; // deactivate the column displays
reg [4:0] state;
reg R1, R2, R3, R4, C1, C2, C3;
initial
begin
R1 = 1;
R2 = 1;
R3 = 1;
R4 = 1;
C1 = 1;
C2 = 1;
C3 = 1;
end
always @*
begin
R1 = ROW1;
R2 = ROW2;
R3 = ROW3;
R4 = ROW4;
C1 = COL1;
C2 = COL2;
C3 = COL3;
end
//////keypad reads 0s so set all to default 1, and send 0's to row and read columns
always @(*)
begin
if( (R1==0) && (C1==0))
state <= 1; //1
else if( (R1==0) && (C2==0))
state <= 2; //2
else if( (R1==0) && (C3==0))
state <= 3;//3
//////////
else if( (R2==0) && (C1==0))
state <= 4; //4
else if( (R2==0) && (C2==0))
state <= 5;//5
else if( (R2==0) && (C3==0))
state <= 6;//6
/////////////
else if( (R3==0) && (C1==0))
state <= 7;//7
else if( (R3==0) && (C2==0))
state <= 8;//8
else if( (R3==0) && (C3==0))
state <= 9;//9
////////////
else if( (R4==0) && (C2==0))
state <= 0;//0
//////////////
else state <= 15;
end
always @(state)
begin
case (state)
0:IO_SSEG = 7'b1000000;//0
1:IO_SSEG = 7'b1111001;//1
2:IO_SSEG = 7'b0100100;//2
3:IO_SSEG = 7'b0110000;//3
4:IO_SSEG = 7'b0011001;//4
5:IO_SSEG = 7'b0010010;//5
6:IO_SSEG = 7'b0000010;//6
7:IO_SSEG = 7'b1111000;//7
8:IO_SSEG = 7'b0000000;//8
9:IO_SSEG = 7'b0011000;//9
15:IO_SSEG = 7'b0101010;//default random light sequence
endcase
end
endmodule
和我的 .ucf 文件:
# IO Board Display Segment a
NET "IO_SSEG<0>" LOC = P102; #a
NET "IO_SSEG<1>" LOC = P105; #b
NET "IO_SSEG<2>" LOC = P101; #c
NET "IO_SSEG<3>" LOC = P97; #d
NET "IO_SSEG<4>" LOC = P98; #e
NET "IO_SSEG<5>" LOC = P100; #f
NET "IO_SSEG<6>" LOC = P104; #g
#NET "IO_SSEG<7>" LOC = P99; #decimal point
#====================================================
# IO Board Seven Segment Digits
#NET "IO_SSEGD<0>" LOC = P92;
#NET "IO_SSEGD<1>" LOC = P93;
#NET "IO_SSEGD<2>" LOC = P84;
#NET "IO_SSEGD<3>" LOC = P88;
#====================================================
# IO Board Seven Segment Display Colon
NET "IO_SSEG_COL" LOC = P87;
#====================================================
# IO Board Pushbutton Switches
# Pushbutton Determines which Digit to Enable
#NET "IO_PB<3>" LOC = P80 | PULLUP;
#NET "IO_PB<2>" LOC = P81 | PULLUP;
#NET "IO_PB<1>" LOC = P78 | PULLUP;
#NET "IO_PB<0>" LOC = P79 | PULLUP;
#====================================================
# IO Board Dip Switchs
#NET "IO_DSW<7>" LOC = P55 | PULLUP;
#NET "IO_DSW<6>" LOC = P56 | PULLUP;
#NET "IO_DSW<5>" LOC = P57 | PULLUP;
#NET "IO_DSW<4>" LOC = P58 | PULLUP;
#NET "IO_DSW<3>" LOC = P61 | PULLUP;
#NET "IO_DSW<2>" LOC = P62 | PULLUP;
#NET "IO_DSW<1>" LOC = P66 | PULLUP;
#NET "IO_DSW<0>" LOC = P67 | PULLUP;
#====================================================
# Clock signal
NET "M_CLOCK" LOC = P123;
NET "ROW1" LOC = P118; // 0N0
NET "ROW2" LOC = P120; // 0N1
NET "ROW3" LOC = P126; // 0N2
NET "ROW4" LOC = P131; // 0N3
NET "COL1" LOC = P133 | PULLUP; // 0N4
NET "COL2" LOC = P137 | PULLUP; // 0N5
NET "COL3" LOC = P139 | PULLUP; // 0N6
我正在使用我的另一个项目中的 .ucf 文件,这就是为什么有这么多注释掉的原因。
在我看来,我的代码是这样工作的:
R1-R4 和 C1-C3 是从 1 开始的变量,因为键盘会扫描短路引脚。这些变量设置为等于 ROW1-4 和 COL1-3,因为我显然无法将输入设置为具有初始值。
然后我有一个始终块,用于检查哪些引脚短路,并根据应该是哪个按钮设置状态。
然后有限状态机检查状态并显示按下到我的 IO 板上的 7 段的数字。
在我的 ucf 文件中,我有一些设置为引体向上,正如我的教授告诉我的那样,这是必要的,但我不知道这实际上改变了什么。有一次他提到有些行或列需要设置为输入,有些需要设置为输出,但我又不知道如何处理这些信息,而且我找不到太多可以帮助我整理头脑的东西围绕这个。
在此先感谢您的帮助。
科迪
谁能找出我做错了什么?
输入M_CLOCK, // FPGA时钟
您的设计中没有使用!!!!!!
有限状态机永远无法改变自己的状态,因为缺少时钟信号。
...
always @(posedge clk //ATTENTION
if ...
state <= 1
else
state <=2
...
我已经坚持了一段时间。 对于我的项目,我正在尝试使用键盘输入制作数字锁。 我有一个 4X4 键盘,但我只使用了其中的 3 列。 目前,我只是想让键盘正常工作。 当我编译它时,我的默认情况下有效,但当我按下任何按钮时都不会改变。
`timescale 1ns / 1ps
module KeypadShit(input M_CLOCK, // FPGA clock
input ROW1, ROW2, ROW3, ROW4, COL1, COL2, COL3,
output [3:0] IO_SSEGD, // IO Board Seven Segment Digits
output reg [7:0] IO_SSEG, // 7=dp, 6=g, 5=f,4=e, 3=d,2=c,1=b, 0=a
output IO_SSEG_COL); // Seven segment column
assign IO_SSEGD = 4'b0111;
assign IO_SSEG_COL = 1; // deactivate the column displays
reg [4:0] state;
reg R1, R2, R3, R4, C1, C2, C3;
initial
begin
R1 = 1;
R2 = 1;
R3 = 1;
R4 = 1;
C1 = 1;
C2 = 1;
C3 = 1;
end
always @*
begin
R1 = ROW1;
R2 = ROW2;
R3 = ROW3;
R4 = ROW4;
C1 = COL1;
C2 = COL2;
C3 = COL3;
end
//////keypad reads 0s so set all to default 1, and send 0's to row and read columns
always @(*)
begin
if( (R1==0) && (C1==0))
state <= 1; //1
else if( (R1==0) && (C2==0))
state <= 2; //2
else if( (R1==0) && (C3==0))
state <= 3;//3
//////////
else if( (R2==0) && (C1==0))
state <= 4; //4
else if( (R2==0) && (C2==0))
state <= 5;//5
else if( (R2==0) && (C3==0))
state <= 6;//6
/////////////
else if( (R3==0) && (C1==0))
state <= 7;//7
else if( (R3==0) && (C2==0))
state <= 8;//8
else if( (R3==0) && (C3==0))
state <= 9;//9
////////////
else if( (R4==0) && (C2==0))
state <= 0;//0
//////////////
else state <= 15;
end
always @(state)
begin
case (state)
0:IO_SSEG = 7'b1000000;//0
1:IO_SSEG = 7'b1111001;//1
2:IO_SSEG = 7'b0100100;//2
3:IO_SSEG = 7'b0110000;//3
4:IO_SSEG = 7'b0011001;//4
5:IO_SSEG = 7'b0010010;//5
6:IO_SSEG = 7'b0000010;//6
7:IO_SSEG = 7'b1111000;//7
8:IO_SSEG = 7'b0000000;//8
9:IO_SSEG = 7'b0011000;//9
15:IO_SSEG = 7'b0101010;//default random light sequence
endcase
end
endmodule
和我的 .ucf 文件:
# IO Board Display Segment a
NET "IO_SSEG<0>" LOC = P102; #a
NET "IO_SSEG<1>" LOC = P105; #b
NET "IO_SSEG<2>" LOC = P101; #c
NET "IO_SSEG<3>" LOC = P97; #d
NET "IO_SSEG<4>" LOC = P98; #e
NET "IO_SSEG<5>" LOC = P100; #f
NET "IO_SSEG<6>" LOC = P104; #g
#NET "IO_SSEG<7>" LOC = P99; #decimal point
#====================================================
# IO Board Seven Segment Digits
#NET "IO_SSEGD<0>" LOC = P92;
#NET "IO_SSEGD<1>" LOC = P93;
#NET "IO_SSEGD<2>" LOC = P84;
#NET "IO_SSEGD<3>" LOC = P88;
#====================================================
# IO Board Seven Segment Display Colon
NET "IO_SSEG_COL" LOC = P87;
#====================================================
# IO Board Pushbutton Switches
# Pushbutton Determines which Digit to Enable
#NET "IO_PB<3>" LOC = P80 | PULLUP;
#NET "IO_PB<2>" LOC = P81 | PULLUP;
#NET "IO_PB<1>" LOC = P78 | PULLUP;
#NET "IO_PB<0>" LOC = P79 | PULLUP;
#====================================================
# IO Board Dip Switchs
#NET "IO_DSW<7>" LOC = P55 | PULLUP;
#NET "IO_DSW<6>" LOC = P56 | PULLUP;
#NET "IO_DSW<5>" LOC = P57 | PULLUP;
#NET "IO_DSW<4>" LOC = P58 | PULLUP;
#NET "IO_DSW<3>" LOC = P61 | PULLUP;
#NET "IO_DSW<2>" LOC = P62 | PULLUP;
#NET "IO_DSW<1>" LOC = P66 | PULLUP;
#NET "IO_DSW<0>" LOC = P67 | PULLUP;
#====================================================
# Clock signal
NET "M_CLOCK" LOC = P123;
NET "ROW1" LOC = P118; // 0N0
NET "ROW2" LOC = P120; // 0N1
NET "ROW3" LOC = P126; // 0N2
NET "ROW4" LOC = P131; // 0N3
NET "COL1" LOC = P133 | PULLUP; // 0N4
NET "COL2" LOC = P137 | PULLUP; // 0N5
NET "COL3" LOC = P139 | PULLUP; // 0N6
我正在使用我的另一个项目中的 .ucf 文件,这就是为什么有这么多注释掉的原因。
在我看来,我的代码是这样工作的:
R1-R4 和 C1-C3 是从 1 开始的变量,因为键盘会扫描短路引脚。这些变量设置为等于 ROW1-4 和 COL1-3,因为我显然无法将输入设置为具有初始值。 然后我有一个始终块,用于检查哪些引脚短路,并根据应该是哪个按钮设置状态。
然后有限状态机检查状态并显示按下到我的 IO 板上的 7 段的数字。
在我的 ucf 文件中,我有一些设置为引体向上,正如我的教授告诉我的那样,这是必要的,但我不知道这实际上改变了什么。有一次他提到有些行或列需要设置为输入,有些需要设置为输出,但我又不知道如何处理这些信息,而且我找不到太多可以帮助我整理头脑的东西围绕这个。
在此先感谢您的帮助。
科迪
谁能找出我做错了什么?
输入M_CLOCK, // FPGA时钟
您的设计中没有使用!!!!!!
有限状态机永远无法改变自己的状态,因为缺少时钟信号。
...
always @(posedge clk //ATTENTION
if ...
state <= 1
else
state <=2
...