Verilog-HDL工程实践入门 学习分享
1 硬件描述语言
1.1 基本逻辑电路的Verilog—HDL描述
- 与非门电路描述
module AND_G2(A,B,F);
input A,B;
output F;
assign F = A & B;
endmodule
- 与非门逻辑电路的描述
module NAND_G2(A,B,F);
input A,B;
output F;
assign F = ~(A&B);
endcodule
- 非门逻辑电路描述
module NOT_G(A,F);
input A;
output F;
assign F=~A;
endmodule
- 或门逻辑电路
module OR_G2(A,B,F);
input A,B;
output F;
assign F = A|B;
endmodule;
- 或非门逻辑电路
module NOR_G2(A,B,F);
input A,B;
output F;
assign F = ~(A|B);
endmodule
- 缓冲器逻辑电路描述
module BUF_G(A,F);
input A;
output F;
assign F=A;
endmodule
1.2 逻辑仿真编写
例1:
顶层模块编写
/** 二与门逻辑模块的顶层模块 */
`timescale 1ns/1ns // 单位和精度都设定为1ns
module AND_G2_TEST(); // 测试的顶层模块名
reg A,B;
wire F;
// 底层模块调用
AND_G2 AND_G2(A,B,F); // 底层模块名,实例名及参数定义
initial begin
A=0;B=0;
#100 A=1;
#100 A=0;B=1;
#100 A=1;
#200 $finish;
end
endmodule
例2:
// 顶层功能模块编写
module AND2(A,B,F);
input A,B;
output F;
assign F = A &B;
endmodule
// tb 编写
module AND2_tb();
reg A,B;
wire F;
AND2 AND2(A,B,F);
initial begin
A=0;B=0;
#100 A=1;
#100 A=0;B=1;
#100 A=1;
#200 $finish;
end
endmodule
3 组合逻辑电路
3.1 数据选择器–多路开关
逻辑功能:是在地址选择器号的控制下,从多路输入数据中选择某一路数据作为输出。
module SELE(A,B,SEL,F);
input A,B,SEL;
output F;
assign F = ~SEL &A | SEL & B;
assign F = ~SEL & A | SEL & B;
endmodule
// 四选1,根据真值表确定表达式
module SELE(A,B,C,D,SEL,F);
input A,B,C,D;
input[1:0] SEL;
output F;
// 这个太变态了,根本想不到,太复杂了
assign F = ~SEL[1] & ~SEL[0] & A |~SEL[1] &SEL[0] & B | SEL[1] & ~SEL[0] &C | SEL[1] & SEL[0] & D ;
endmodule
2 数据选择器的行为描述方式
行为描述相当于在软件设计过程中的流程图描述和算法描述,它种种表达的是工作的抽象或者说是软件功能的行为表现,而不是具体的实现手段和方法。在行为描述的基础上,经过论证是可行的话,才考虑用哪种语言来表现。
module SELE(A,B,C,D,SEL,F);
input A,B,C,D;
input[1:0] SEL;
output F;
assign F = SEL4_1_FUNC(A,B,C,D,SEL);
function SEL4_1_FUNC;
input A,B,C,D;
input[1:0] SEL;
case(SEL)
0:SEL4_1_FUNC = A;
1:SEL4_1_FUNC = B;
2:SEL4_1_FUNC = C;
3:SEL4_1_FUNC = D;
endcase
endfunction
endmodule
module SELE(A,B,SEL,F);
input A,B,SEL;
output F;
assign F =SEL2_1_FUNC(A,B,SEL);
function SEL2_FUNC;
input A,B,SEL;
if(SEL == 0)
SEL2_1_FUNC =A;
else
SEL2_1_FUNC =B;
endfunction
endmodule
module SELE(A,B,C,D,SEL,F);
input A,B,C,D;
input[1:0] SEL;
output F;
assign F = SEL4_1_FUNC(A,B,C,D,SEL);
function SEL4_1_FUNC;
input A,B,C,D;
input[1:0] SEL;
case(SEL)
0:SEL4_1_FUNC = A;
1:SEL4_1_FUNC = B;
2:SEL4_1_FUNC = C;
3:SEL4_1_FUNC = D;
endcase
endfunction
endmodule
3.2 数据比较电路
例子:行为描述方式的2位数据比较器
module COMP(A,B,LG,EQ,SM);
input [1:0] A,B;
input LG,EQ,SM;
assign {LG,EQ,SM} = FUNC_COMP(A,B);
function [2:0] FUNC_COMP;
input [1:0] A,B;
if(A>B)
FUNC_COMP = 3'b100;
else if(A<B)
FUNC_COMP = 3'b001;
else
FUNC_COMP =3'b010;
endfunction
endmodule
例子2:4位数据比较器的逻辑仿真结果
module COMP(A,B,LG,EQ,SM);
input[3:0] A,B;
output LG,EQ,SM;
assign {LG,EQ,SM} = FUNC_COMP(A,B);
input[3:0] A,B;
function[2:0] FUNC_COMP;
input [3:0] A,B;
if(A>B)
FUNC_COMP = 3'b100;
else if(A<B)
FUNC_COMP =3‘b010;
else
FUNC_COMP =3'b010;
endfunction
endmudule
3.3 编码器
`define SW_IN0 4'b0001
`define SW_IN1 4b0010
`define SW_IN2 4'b0100
`define SW_IN3 4'b1000
module ENC(IN,Y);
input [3:0] IN;
input [1:0] Y;
assign Y = FUNC_ENC;
function[1:0] FUNC_ENC;
input [3:0] IN;
case(IN)
`SW_IN0:FUNC_ENC =0;
`SW_IN1:FUNC_ENC=1;
`SW_IN2:FUNC_ENC=2;
`SW_IN3:FUNC_ENC=3;
endcase
endfunction
endmodule
3.4 BCD段译码器
`define OUT_0 10'b0000000001
`define OUT_1 10'b0000000010
`define OUT_2 10'b0000000100
`define OUT_3 10'b0000001000
`define OUT_4 10'b0000010000
`define OUT_5 10'b0000100000
`define OUT_6 10'b0001000000
`define OUT_7 10'b0010000000
`define OUT_8 10'b0100000000
`define OUT_9 10'b1000000000
/* DECODER */
module DEC(IN,OUT,ERR);
input [3:0] IN;
output[9:0] OUT;
output ERR;
assign {ERR,OUT} = FUNC_DEC(IN);
function [10:0] FUNC_DEC;
input [3:0] IN;
case(IN)
0:FUNC_DEC = {1'b0,`OUT_0};
1:FUNC_DEC = {1'b0,`OUT_1};
2:FUNC_DEC = {1'b0,`OUT_2};
3:FUNC_DEC = {1'b0,`OUT_3};
4:FUNC_DEC = {1'b0,`OUT_4};
5:FUNC_DEC = {1'b0,`OUT_5};
6:FUNC_DEC = {1'b0,`OUT_6};
7:FUNC_DEC = {1'b0,`OUT_7};
8:FUNC_DEC = {1'b0,`OUT_8};
9:FUNC_DEC = {1'b0,`OUT_9};
default:FUNC_DEC = {1'b1,`OUT_ERR};
endcase
endfunction
endmodule
4 触发器
4.1 异步RS触发器
module RS_FF(R,S,Q,QB);
input R,S;
output Q,QB;
reg Q,QB;
always @(R or S) begin
case({R,S})
0:begin Q<=Q;QB<=QB;end
1:begin Q<=1;QB<=0 ;end
2:begin Q<=0;QB<=1; end
3:begin Q<=1'bx;QB<=1'bx;end
endcase
end
endmodule
4.2 同步RS触发器
module SY_RS_FF(R,S,CLK,Q,QB);
input R,S,CLK;
output Q,QB;
reg Q;
assign QB=~QB;
always@(posedge CLK) begin
case({R,S})
0:Q<=0;
1:Q<=1;
2:Q<=0;
3:Q<=1'bx;
endcase
end
endmodule
4.3 异步T触发器
module T_FF(R,T,Q,QB);
input R,T;
input Q,QB;
reg Q;
assign QB=~Q;
always@(posedge T or negedge R) begin
Q<=(!R)? 0:~Q;
end
endmodule
4.4 同步T触发器
module SY_T_FF(R,T,CLK,Q,QB);
input R,T,CLK;
output Q,QB;
reg Q;
assign QB=~Q;
always@(posedge CLK or negedge R) begin
if(!R)
Q<=0;
else if(T)
Q<=~Q;
end
endmodule
4.5 带有复位端的同步D触发器
module R_SY_D_FF(R,D,CLK,Q,QB);
input R,D,CLK;
output Q,QB;
reg Q;
assgin QB =~Q;
always@(posedge CLK or negedge R) begin
Q <= (!R) ? 0:D;
end
endmodule
4.6 同步JK触发器
module SY_JK_FF(J,K,CLK,Q,QB);
input J,K,CLK;
output Q,QB;
reg Q;
assign QB=~Q;
always @(posedge CLK) begin
case({J,K})
0: Q<=Q;
1: Q<=0;
2: Q<=1;
3: Q<=~Q;
endcase
end
endmodule
4.7 同步D触发器
module SY_D_FF(D,CLK,Q,QB);
input D,CLK;
output Q,QB;
reg Q;
assign QB= ~Q;
always@(posedge CLK) begin
Q<=D;
end
endmodule
未完待续…
【参考文献】
Verilog-HDL工程实践入门 常晓明老师著