学习并掌握Verilog HDL为FPGA等的学习提供基础,基于课堂上刚学完的数字电路逻辑,现利用Verilog语言进行对数字电路中的常见电路进行描述,从中加深对数字电路逻辑的理解以及对Verilog的熟练应用。(代码参考自网上)
1.一位半加器电路:
加法器是逻辑运算电路中最基础的组成单元。将如果不考虑有来自低位的进位, 将两个二进制数相加, 称为半加, 实现半加的电路叫做半加器。1位半加器每次对两个1位的二级制数进行相加。按照二进制加法运算规则, 可以得到如下表所示的半加器真值表。
sum = A’B + AB’ = A⊕B
CO= AB
module halfadder (
input A, //第一个加数a
input B, //第二个加数b
output sum, //a与b的加和
output co //a与b的进位
);
xor (sum, A, B) ; //门电路XOR (输出, 输入1, 输入2)
and (co, A, B) ; //门电路AND (输出, 输入1, 输入2)
endmodule
2.一位全加器电路:
在将两个多位二进制数相加时,除了最低位以外,每一位都应该考虑来自低位的进位,即将两个对应位的加数和来自低位的进位三个数相加。这种运算称为全加,所用的电路称为全加器。按照二进制加法运算规则,可以得到如下表所示全加器真值表。其中,A、B是两个加数,CI是来自低位的进位,S是相加的和,CO是向高位的进位。将S、CO和A、B、CI的关系写成逻辑表达式则得到:
S=CI’A’B+CI’AB’+CIA’B’+CIAB=A⊕B⊕CI
CO=CI’AB+CIA’B+CI’AB’+CIAB=AB+AC+BC
module adder1
(
input wire a, //输入的低位进位及两个加数cin、a、b
input wire b,
input wire cin,
output wire sum, //输出的和与进位
output wire cout
);
wire s1,s2,s3; //定义中间变量
xor (s1,a,b); //调用基本异或门
xor (sum,s1,cin);
nand (s2,a,b); //调用基本与非门
nand (s3,s1,cin);
and (cout,s2,s3);
endmodule
3.三变量表决器:
3变量的多数表决器,即当三个人中有两个及以上投票的,则通过。定义三个变量A、B、C及投票结果Y,可以得到如下所示的真值表。将Y和A、B、C的关系写成逻辑表达式则得到:
Y=A’BC+AB’C+ABC’+ABC=AB+BC+AC
module voter3
(
input wire a, //3个输入变量a、b、c
input wire b,
input wire c,
output wire led //显示表决结果led
);
assign led = (a&b)|(b&c)|(a&c); //根据逻辑表达式得到表决结果
endmodule
4.一位二进制比较器:
1位二进制数的比较器,即对输入的两个数进行比较,输出三种结果。当A>B时,Y(A>B)为真。当AB),Y(A=B),Y(A
Y(A Y(A=B)=AB+A’B’=A⊙B
Y(A>B)=AB’
module comparer1
(
input wire a, //定义输入的两个数a、b
input wire b,
output wire led1, //定义三种输出结果对应的led
output wire led2,
output wire led3
);
assign led1 = (!a)&b; //ab
endmodule
5.2-4译码器电路:
2-4译码器,输入的2位二进制代码共有四种状态,译码器将每个输入代码译成对应的一根输出线上的高、低电平信号。由此可得如下的真值表。将输入的A、B和输出Y0、Y1、Y2、Y3的关系写成逻辑表达式则得到:
Y0=A’B’
Y1=A’B
Y2=AB’
Y3=AB
module decode24
(
input wire [1:0] a, //定义两位输入
output reg [3:0] led //定义输出的4位译码结果对应的led
);
//always块语句,a值变化时执行一次过程块
always@(a)
begin
case(a)
2'b00: led = 4'b0001; //2-4译码结果
2'b01: led = 4'b0010;
2'b10: led = 4'b0100;
2'b11: led = 4'b1000;
endcase
end
endmodule
6.四选一多路选择器:
4选1多路选择器,即从输入的四个数据中选择其中一个。通过定义两个变量,产生四种状态,分别对应四个数据的输出。由此可得到如下真值表。将输入的a,b,c,d,s0,s1和输出Y的关系写成逻辑表达式则打得到:
Y=a(s0’s1’)+b(s0’s1)+c(s0s1’)+d(s0s1)
module mult4
(
input wire a, //定义四位输入
input wire b,
input wire c,
input wire d,
input wire [1:0] sel, //定义输出的选择变量
output reg led //定义选择器输出结果对应的led
);
always@(sel) //根据sel结果选择输出,当sel变化时执行
begin
case(sel)
2'b00: led = a;
2'b01: led = b;
2'b10: led = c;
2'b11: led = d;
endcase
end
endmodule
8.数码管:
数码管是工程设计中使用很广的一种显示输出器件。一个7段数码管(如果包括右下的小点可以认为是8段)分别由a、b、c、d、e、f、g位段和表示小数点的dp位段组成。实际是由8个LED灯组成的,控制每个LED的点亮或熄灭实现数字显示。通常数码管分为共阳极数码管和共阴极数码管,结构如下图所示:
共阴8段数码管的信号端低电平有效,而共阳端接高电平有效。当共阳端接高电平时只要在各个位段上加上相应的低电平信号就可以使相应的位段发光。比如:要使a段发光,则在a段信号端加上低电平即可。共阴极的数码管则相反。 可以看到数码管的控制和LED的控制有相似之处。
module segment
(
input wire [3:0] seg_data_1, //四位输入数据信号
input wire [3:0] seg_data_2, //四位输入数据信号
output wire [8:0] segment_led_1, //数码管1,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
output wire [8:0] segment_led_2 //数码管2,MSB~LSB = SEG,DP,G,F,E,D,C,B,A
);
reg[8:0] seg [15:0]; //存储7段数码管译码数据
initial
begin
seg[0] = 9'h3f; // 0
seg[1] = 9'h06; // 1
seg[2] = 9'h5b; // 2
seg[3] = 9'h4f; // 3
seg[4] = 9'h66; // 4
seg[5] = 9'h6d; // 5
seg[6] = 9'h7d; // 6
seg[7] = 9'h07; // 7
seg[8] = 9'h7f; // 8
seg[9] = 9'h6f; // 9
seg[10]= 9'h77; // A
seg[11]= 9'h7C; // b
seg[12]= 9'h39; // C
seg[13]= 9'h5e; // d
seg[14]= 9'h79; // E
seg[15]= 9'h71; // F
end
assign segment_led_1 = seg[seg_data_1];
assign segment_led_2 = seg[seg_data_2];
endmodule