牛客网verilog题库——VL14
题目:用优先编码器实现键盘编码电路
请使用优先编码器①实现键盘编码电路,可添加并例化题目中已给出的优先编码器代码。
10个按键分别对应十进制数0-9,按键9的优先级别最高;按键悬空时,按键输出高电平,按键按下时,按键输出低电平;键盘编码电路的输出是8421BCD码。
要求:键盘编码电路要有工作状态标志,以区分没有按键按下和按键0按下两种情况。
优先编码器真值表如下图:
`timescale 1ns/1ns module encoder_0( input [8:0] I_n , output reg [3:0] Y_n ); always @(*)begin casex(I_n) 9'b111111111 : Y_n = 4'b1111; 9'b0xxxxxxxx : Y_n = 4'b0110; 9'b10xxxxxxx : Y_n = 4'b0111; 9'b110xxxxxx : Y_n = 4'b1000; 9'b1110xxxxx : Y_n = 4'b1001; 9'b11110xxxx : Y_n = 4'b1010; 9'b111110xxx : Y_n = 4'b1011; 9'b1111110xx : Y_n = 4'b1100; 9'b11111110x : Y_n = 4'b1101; 9'b111111110 : Y_n = 4'b1110; default : Y_n = 4'b1111; endcase end endmodule module key_encoder( input [9:0] S_n , output wire[3:0] L , output wire GS ); endmodule补全代码:
答案
一共有十个案件,对应I_0,I_1,I_2......I_9
按下的按键是0,悬空是1
比如表里的第一行,意思就是如果1-9这9个按键都没被按下,那输出的是1111
第二行就是按键9被按下,其他无所谓,就会输出0110
S_n就是输入的那十个按键
L就是输出的四位BCD码
GS用来区分按下0还是没有按键按下
实际上考的就是怎么用9线程的优先编码器拼成一个10线程的按键编码器
先例化一下这个9线程的优先编码器,输入就是1-9这9位,0先不算,因为encoder不处理按键0
按键9被按下,输出的应该是1001,但是编码器真值表出来的是0110,所以输出的是反码
所以说,GS的生成逻辑就是判断S_n中有没有0,就是有没有按键被按下,用归约
如果S_n中有按键被按下,那就输出1,如果没有按键被按下,那就输出0
如果1-9当中至少有一个被按下了,那么L=Y_n的取反,如果没有按键按下,那输出L就是0000,然后靠GS区分,如果GS=0,那就没有按键被按下,如果GS=1,那就是0被按下了
`timescale 1ns/1ns module encoder_0( input [8:0] I_n , output reg [3:0] Y_n ); always @(*)begin casex(I_n) 9'b111111111 : Y_n = 4'b1111; 9'b0xxxxxxxx : Y_n = 4'b0110; 9'b10xxxxxxx : Y_n = 4'b0111; 9'b110xxxxxx : Y_n = 4'b1000; 9'b1110xxxxx : Y_n = 4'b1001; 9'b11110xxxx : Y_n = 4'b1010; 9'b111110xxx : Y_n = 4'b1011; 9'b1111110xx : Y_n = 4'b1100; 9'b11111110x : Y_n = 4'b1101; 9'b111111110 : Y_n = 4'b1110; default : Y_n = 4'b1111; endcase end endmodule module key_encoder( input [9:0] S_n , output wire[3:0] L , output wire GS ); wire [3:0] Y_n; encoder_0 encoder_0( .I_n(S_n[9:1]), .Y_n(Y_n) ); assign L = ~Y_n; assign GS = ((Y_n == 4'b1111) && (S_n[0] == 1)) ? 0 : 1; endmodule