11.4位数值比较器电路
- 第一点:如何进行三种状态的判断,>、<、=这三种状态,=可以通过,即不大于也不小于来进行判断。
- 第二点:只有当>、<都不能满足的情况下,才能进行下一位的a、b判断,不然会出现竞争。
- 第三点:最后再output的输出
`timescale 1ns/1ns
module comparator_4(
input [3:0] A ,
input [3:0] B ,
output wire Y2 , //A>B
output wire Y1 , //A=B
output wire Y0 //A<B
);
wire [7:0] sel;
assign sel[7] = (A[3] > B[3])? 1'b1:1'b0;
assign sel[6] = (A[3] < B[3])? 1'b1:1'b0;
assign sel[5] = (A[2] > B[2] && sel [7:6] == 2'd0 )? 1'b1:1'b0;
assign sel[4] = (A[2] < B[2] && sel [7:6] == 2'd0 )? 1'b1:1'b0;
assign sel[3] = (A[1] > B[1] && sel [7:4] == 4'd0 )? 1'b1:1'b0;
assign sel[2] = (A[1] < B[1] && sel [7:4] == 4'd0 )? 1'b1:1'b0;
assign sel[1] = (A[0] > B[0] && sel [7:2] == 6'd0 )? 1'b1:1'b0;
assign sel[0] = (A[0] < B[0] && sel [7:2] == 6'd0 )? 1'b1:1'b0;
assign Y2 = (sel == 8'b1000_0000 || sel == 8'b0010_0000 || sel == 8'b0000_1000 || sel == 8'b0000_0010)?1'b1:1'b0;
assign Y0 = (sel == 8'b0100_0000 || sel == 8'b0001_0000 || sel == 8'b0000_0100 || sel == 8'b0000_0001)?1'b1:1'b0;
assign Y1 = (sel == 8'b0000_0000)?1'b1:1'b0;
endmodule
12.4 bit超前进位加法器电路
- 采用超前进位加法器,首先得体会超前进位加法器和加法器之前的区别,采用加法器在进位时,必须等到前一个加法器完成加法运算后,才能到下一个加法器,进行加法处理。而采用超前进位加法器,是所有的加法器进行加法处理,最后再进行累加,实现加法功能。是一种典型的面积换速度的思想。
- 简单的加法器,都可以采用assign {cout,sum} = a + b + cin;
- 但是采用超前进位加法器,则需要将sum和cout分开计算,需要将二者的电路分离开,不采用较多的复用电路。
`timescale 1ns/1ns
module lca_4(
input [3:0] A_in ,
input [3:0] B_in ,
input C_1 ,
output wire CO ,
output wire [3:0] S
);
wire [3:0] C;
assign S[0] = A_in[0] ^ B_in[0] ^ C_1;
assign S[1] = A_in[1] ^ B_in[1] ^ C[0];
assign S[2] = A_in[2] ^ B_in[2] ^ C[1];
assign S[3] = A_in[3] ^ B_in[3] ^ C[2];
assign C[0] = (A_in[0] & B_in[0]) + ((A_in[0] ^ B_in[0]) & C_1);
assign C[1] = (A_in[1] & B_in[1]) + ((A_in[1] ^ B_in[1]) & C[0]);
assign C[2] = (A_in[2] & B_in[2]) + ((A_in[2] ^ B_in[2]) & C[1]);
assign C[3] = (A_in[3] & B_in[3]) + ((A_in[3] ^ B_in[3]) & C[2]);
assign CO = C[3];
endmodule
13.优先编码器电路
- 相对来说比较简单,只要简单的按照图片的功能进行描述即可
`timescale 1ns/1ns
module encoder_0(
input [8:0] I_n ,
output reg [3:0] Y_n
);
always@(*)begin
casex(I_n)
9'b1_1111_1111: Y_n = 4'b1111;
9'b0_xxxx_xxxx: Y_n = 4'b0110;
9'b1_0xxx_xxxx: Y_n = 4'b0111;
9'b1_10xx_xxxx: Y_n = 4'b1000;
9'b1_110x_xxxx: Y_n = 4'b1001;
9'b1_1110_xxxx: Y_n = 4'b1010;
9'b1_1111_0xxx: Y_n = 4'b1011;
9'b1_1111_10xx: Y_n = 4'b1100;
9'b1_1111_110x: Y_n = 4'b1101;
9'b1_1111_1110: Y_n = 4'b1110;
endcase
end
endmodule
14.用优先编码器1实现键盘编码电路
这里采用了博客中他人的说法:
- 首先要确定电路输出L是8421BCD码,即高电平有效,而题目中给出的优先编码输出Y_n是低电平有效的,故应当明确L和Y_n两者的状态是恰好相反的;
- 按键有10个按键,而编码器只有9个输入状态;
- 此题关键在于着重理解:键盘编码电路要有工作状态标志,以区分没有按键按下和按键0按下两种情况。
- 简单来说就是,无按键按下,和按键0按下时,电路的输出L的状态是一样的,因此在这种情况下可以通过GS信号来区分键盘是否处在工作状态。
键盘按键 | S[9:0] | L[3:0] | GS |
---|---|---|---|
无按键按下 | 1_1111_1111 | 0000 | 0 |
按键0按下 | 1_1111_1110 | 0000 | 1 |
`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] L_wire;
encoder_0 encoder_0_inst(
.I_n(S_n[9:1]),
.Y_n(L_wire)
);
assign GS = ~((&L_wire) & S_n[0]);
assign L = ~L_wire;
endmodule
15.优先编码器 I
- 代码整体比较简单,即按表格进行描述即可
- 注意数据类型的转变
- 注意8’b0000_0000和8’b0000_0001的关系,其余采用casex即可。
`timescale 1ns/1ns
module encoder_83(
input [7:0] I ,
input EI ,
output wire [2:0] Y ,
output wire GS ,
output wire EO
);
reg [2:0] Y_reg;
reg GS_reg;
reg EO_reg;
always@(*)begin
if(EI == 1'b0)begin
Y_reg <= 3'b0;
GS_reg <= 1'b0;
EO_reg <= 1'b0;
end
else begin
casex(I)
8'b1xxx_xxxx:begin
Y_reg <= 3'b111;
GS_reg <= 1'b1;
EO_reg = 1'b0;
end
8'b01xx_xxxx:begin
Y_reg <= 3'b110;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b001x_xxxx:begin
Y_reg <= 3'b101;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b0001_xxxx:begin
Y_reg <= 3'b100;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b0000_1xxx:begin
Y_reg <= 3'b011;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b0000_01xx:begin
Y_reg <= 3'b010;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b0000_001x:begin
Y_reg <= 3'b001;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
8'b0000_0000:begin
Y_reg <= 3'b000;
GS_reg <= 1'b0;
EO_reg <= 1'b1;
end
8'b0000_0001:begin
Y_reg <= 3'b000;
GS_reg <= 1'b1;
EO_reg <= 1'b0;
end
default:
Y_reg <= 3'b000;
endcase
end
end
assign Y = Y_reg;
assign GS = GS_reg;
assign EO = EO_reg;
endmodule