
Verilog 基础代码+ModelSim仿真
1. 4位加法器
adder.v
module adder (
input wire [3:0] A,B,
input Ci,
output wire [3:0] Sum,
output Co
);
assign {Co,Sum} = A+B+Ci;
endmodule
tb_adder.v
`timescale 1ns/1ns
`include"../rtl/adder.v"
module adder_tb;
reg [3:0]a,b;
reg ci;
wire [3:0]Sum;
wire Co;
integer i,j;
adder U1(.A(a),
.B(b),
.Ci(ci),
.Sum(Sum),
.Co(Co));
initial begin
a=0;
b=0;
for(i=0;i<16;i=i+1)
for(j=0;j<16;j=j+1) begin
ci=0;
a=i;
b=j;
#10;
ci=1;
a=i;
b=j;
#10;
end
$finish;
end
initial begin
$monitor("%d+%d+%d=%d%d",a,b,ci,Co,Sum);
end
initial begin
$dumpfile("adder.vcd");
$dumpvars(0,adder_tb);
end
endmodule
2. 4位BCD加法器
BCDadder.v
module BCDadder (
input [3:0]A,B,
input Cin,
output [3:0] Sum,
output Co
);
assign {Co,Sum} = ((A+B+Cin)>9)?(A+B+Cin+6):(A+B+Cin);
endmodule
tb_BCD_adder.v
`timescale 1ns/1ns
`include "../rtl/BCDadder.v"
module tb_BCD_adder();
reg [3:0]A,B;
reg Cin;
wire [3:0] Sum;
wire Co;
integer i,j;
BCDadder u_BCDadder(
.A ( A ),
.B ( B ),
.Cin ( Cin ),
.Sum ( Sum ),
.Co ( Co )
);
initial begin
for(i=0;i<10;i=i+1) begin
for(j=0;j<10;j=j+1) begin
Cin=0;
A=i;
B=j;
#10;
$display("A=%d,B=%d,Cin=%d,Sum=%d,Co=%d",A,B,Cin,Sum,Co);
Cin=1;
#10;
$display("A=%d,B=%d,Cin=%d,Sum=%d,Co=%d",A,B,Cin,Sum,Co);
end
end
$finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, tb_BCD_adder);
end
endmodule
3. 八选一数据选择器
MUX81.v
module MUX81 (
input [7:0]IN,
input [2:0]SEL,
output OUT
);
assign OUT =SEL[2]?
(SEL[1]?SEL[0]?IN[7]:IN[6]:SEL[0]?IN[5]:IN[4]):
(SEL[1]?SEL[0]?IN[3]:IN[2]:SEL[0]?IN[1]:IN[0]);
endmodule
4. 3-8译码器
Decode138.v
module Decode138 (
input A,B,C,G1,G2An,G2Bn,
output [7:0] Y
);
assign Y = (G1&(~G2An)&(~G2Bn))?(~(8'b00000001<<{C,B,A})):(8'b11111111);
endmodule
tb_Decode138.v
`include "../rtl/Decode138.v"
`timescale 1ns / 1ns
module tb_Decode138();
reg A,B,C,G1,G2An,G2Bn;
wire [7:0] Y;
integer i;
Decode138 u_Decode138(
.A ( A ),
.B ( B ),
.C ( C ),
.G1 ( G1 ),
.G2An ( G2An ),
.G2Bn ( G2Bn ),
.Y ( Y )
);
initial begin
G2An=0;
G2Bn=0;
G1=1;
repeat(10)
for(i=0;i<7;i=i+1) begin
{C,B,A}=i;
#10;
end
$finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0,tb_Decode138);
end
endmodule
5. 锁存器
_latch.v
module _latch(
input D,SET,CLRn,CLK,
output Q
);
assign Q = CLRn ? (SET ? 1:(CLK ? D:Q)):0;
endmodule
tb_latch.v
`timescale 1ns/1ns
`include "../rtl/_latch.v"
module tb_latch;
reg clk,d,set,clrn;
wire q;
integer i,num;
_latch u1(.CLK(clk),.SET(set),.CLRn(clrn),.D(d),.Q(q));
initial begin
set = 1;
clk =0;
clrn =0;
d=0;
#10 clrn = 1;
#20 d = 1;
#10 d = 0;
#10 set = 0;
for(i=0;i<200;i=i+1) begin
num={$random}%10+1;
#num d=1;
num={$random}%10+1;
#num d=0;
end
$finish;
end
always #10 clk = ~clk;
initial begin
$dumpfile("latch.vcd");
$dumpvars(0,tb_latch);
end
endmodule
6.D触发器
_D_flip_flop.v
module _D_flip_flop(
input wire D,
input wire CLK,
input wire CLRn,
input wire SET,
output reg Q
);
always @(posedge CLK or negedge CLRn ) begin
if(!CLRn)
Q<=0;
else if(SET)
Q<=1;
else if(CLK)
Q<=D;
else
Q<=Q;
end
endmodule
tb_D_flip_flop.v
`timescale 1ns/1ns
`include "../rtl/_D_flip_flop.v"
module tb_D_flip_flop;
reg clk,d,set,clrn;
wire q;
integer i,num;
_D_flip_flop u1(.CLK(clk),.SET(set),.CLRn(clrn),.D(d),.Q(q));
initial begin
set = 1;
clk =0;
clrn =0;
d=0;
#10 clrn = 1;
#20 d = 1;
#10 d = 0;
#10 set = 0;
for(i=0;i<200;i=i+1) begin
num={$random}%10+1;
#num d=1;
num={$random}%10+1;
#num d=0;
end
$finish;
end
always #10 clk = ~clk;
initial begin
$dumpfile("dump.vcd");
$dumpvars(0,tb_D_flip_flop);
end
endmodule
7.模24计数器
_counter.v
module _counter (
input CLK,
input Loadn,
input CLRn,
input [4:0]D,
output reg [4:0] Q,
output reg Co
);
always @(posedge CLK,negedge CLRn) begin
if(~CLRn) begin
Q <= 0;
Co <=0;
end
else if (~Loadn)
Q <= D;
else if(Q==24-1) begin
Q<=0;
Co<=1;
end
else begin
Q<=Q+1;
Co<=0;
end
end
endmodule
tb_counter.v
`timescale 1ns / 1ns
`include "../rtl/_counter.v"
module tb_counter();
reg CLK,Loadn,CLRn;
reg [4:0]D;
wire [4:0]Q;
wire Co;
_counter u1(
.CLK(CLK),
.Loadn(Loadn),
.CLRn(CLRn),
.D(D),
.Q(Q),
.Co(Co)
);
always #10 CLK=~CLK;
initial begin
CLK = 0;
Loadn = 1;
D = 10;
CLRn = 0;
#20 CLRn=1;
D=0;
Loadn = 0;
#20 Loadn = 1;
#2000;
$finish;
end
initial begin
$monitor ("%9t ns Q = %d,Co = %d",$time,Q,Co);
end
initial begin
$dumpfile("counter.vcd");
$dumpvars(0,tb_counter);
end
endmodule
8.偶数12分频器
even_divide.v
module even_divide(
input CLK,
input RSTn,
output reg CLK_12
);
reg [3:0]cnt;
always@(posedge CLK or negedge RSTn) begin
if(!RSTn) begin
cnt<=0;
CLK_12 <= 0;
end
else begin
if(cnt<5)
cnt<=cnt+1;
else begin
cnt<=0;
CLK_12 <= ~CLK_12;
end
end
end
endmodule
tb_even_divide.v
`timescale 1ns/1ns
`include "../rtl/even_divide.v"
module tb_even_divide();
reg CLK,RSTn;
wire CLK_12;
even_divide u1(
.CLK( CLK),
.RSTn( RSTn),
.CLK_12( CLK_12)
);
always #10 CLK=~CLK;
initial begin
CLK = 0;
RSTn=0;
#10 RSTn=1;
#2000;
$finish;
end
initial begin
$dumpfile("even_divide.vcd");
$dumpvars(0,tb_even_divide);
end
endmodule
9.奇数15分频器
odd_divide.v
module odd_divide(
input CLK,
input RSTn,
output CLK_15
);
reg [4:0]cnt1;
reg [4:0]cnt2;
reg clk1,clk2;
always @(posedge CLK or negedge RSTn) begin
if(!RSTn) begin
cnt1<=0;
clk1<=0;
end
else begin
if(cnt1<14)
cnt1<=cnt1+1;
else
cnt1<=0;
if(cnt1<7)
clk1<=1'b1;
else
clk1<=1'b0;
end
end
always @(negedge CLK or negedge RSTn) begin
if(!RSTn) begin
cnt2<=0;
clk2 <= 0;
end
else begin
if(cnt2<14)
cnt2<=cnt2+1;
else
cnt2<=0;
if(cnt2<7)
clk2<=1'b1;
else
clk2<=1'b0;
end
end
assign CLK_15 = clk1 | clk2;
endmodule
tb_odd_divide.v
`timescale 1ns/1ns
`include "../rtl/odd_divide.v"
module tb_odd_divide();
reg CLK;
reg RSTn;
wire CLK_15;
odd_divide U1(.CLK ( CLK ),
.RSTn ( RSTn ),
.CLK_15 ( CLK_15 )
);
always #10 CLK=~CLK;
initial begin
CLK=0;
RSTn=0;
#20 RSTn=1;
#1000;
$finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0,tb_odd_divide);
end
endmodule
10.计数器(状态机写法)
counter.v
module counter(
input clk,
input rst_n,
output [3:0] q,
output reg co
);
parameter s0=0, s1=1, s2=2, s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,s9=9;
reg [3:0] state;
assign q=state;
always @(posedge clk,negedge rst_n) begin
if(!rst_n)
co<=0;
else if(state==s9)
co<=1;
else
co<=0;
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= s0;
end
else begin
case(state)
s0: begin
state <= s1;
end
s1: begin
state <= s2;
end
s2: begin
state <= s3;
end
s3: begin
state <= s4;
end
s4: begin
state <= s5;
end
s5: begin
state <= s6;
end
s6: begin
state <= s7;
end
s7: begin
state <= s8;
end
s8: begin
state <= s9;
end
s9: begin
state <= s0;
end
default: begin
state <= s0;
end
endcase
end
end
endmodule
tb_counter.v
`timescale 1ns/1ns
`include "../rtl/counter.v"
module tb_counter();
reg clk,rst_n;
wire [3:0]q;
wire co;
counter counter_inst(
.clk(clk),
.rst_n(rst_n),
.q(q),
.co(co)
);
always #10 clk = ~clk;
initial begin
clk=0;
rst_n=0;
#10 rst_n=1;
#1000 $finish;
end
initial begin
$dumpfile("counter.vcd");
$dumpvars(0,tb_counter);
end
endmodule
11. 序列检测器(状态机)
检测01101序列
seq.v
module seq(
input clk,
input rst_n,
input data_in,
output data_out
);//01101
parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5;
reg [3:0]state;
assign data_out=(state==s5)?1:0;
always @(posedge clk,negedge rst_n) begin
if(!rst_n) begin
state<=s0;
end
else begin
case(state)
s0:
state<=(data_in)?s0:s1;
s1:
state<=(data_in)?s2:s1;
s2:
state<=(data_in)?s3:s1;
s3:
state<=(data_in)?s0:s4;
s4:
state<=(data_in)?s5:s1;
s5:
state<=(data_in)?s3:s1;
default:
state<=s0;
endcase
end
end
endmodule
tb_seq.v
`timescale 1ns/1ns
`include "../rtl/seq.v"
module tb_counter();
reg clk,rst_n;
reg data_in;
wire data_out;
seq seq_inst(.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.data_out(data_out)
);
always #5 clk = ~clk;
initial begin
clk=0;
rst_n=0;
data_in=0;
#10 rst_n=1;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
#10 data_in=0;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
#10 data_in=0;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
#10 data_in=1;
#10 data_in=1;
#10 data_in=1;
#10 data_in=0;
$finish;
end
initial begin
$dumpfile("seq.vcd");
$dumpvars(0,tb_counter);
end
endmodule
11. 饮料贩卖机(状态机)
drink.v
module drink(
input CLK,RSTn,A,B,//A:0.5 ; B:1
output reg out1,out2
);
parameter s0=0,s1=1,s2=2;
reg [1:0]state;
always@(posedge CLK or negedge RSTn)
if(!RSTn) begin
out1<=0;
out2<=0;
state<=s0;
end
else
case(state)
s0: //0.5
if(A==1&&B==0) begin
out1<=0;
out2<=0;
state<=s1;
end
else if(A==0&&B==1) begin
out1<=0;
out2<=0;
state<=s2;
end
else if(A==0&&B==0) begin
out1<=0;
out2<=0;
state<=s0;
end
s1: //1
if(A==1&&B==0) begin
out1<=0;
out2<=0;
state<=s2;
end
else if(A==0&&B==1) begin
out1<=1;
out2<=0;
state<=s0;
end
else if(A==0&B==0) begin
out1<=0;
out2<=0;
state<=s1;
end
s2: //1.5
if(A==1&&B==0) begin
out1<=1;
out2<=0;
state<= s0;
end
else if(A==0&&B==1) begin
out1<=1;
out2<=1;
state<= s0;
end
else if(A==0&&B==0) begin
out1<=0;
out2<=0;
state<=s2;
end
default: begin
out1<=0;
out2<=0;
state<=s0;
end
endcase
endmodule
tb_drink.v
`timescale 1ns/1ns
`include "../rtl/drink.v"
module tb_drink();
reg CLK,RSTn,A,B;
wire out1,out2;
drink U1(
.CLK(CLK),
.RSTn(RSTn),
.A(A),
.B(B),
.out1(out1),
.out2(out2)
);
always #5 CLK=~CLK;
integer i;
initial begin
CLK=0;
RSTn=0;
A=0;
B=0;
#10 RSTn=1;
#10 A=1;//0.5+0.5+0.5
#10 A=0;
#10 A=1;
#10 A=0;
#10 A=1;
#10 A=0;
#10 A=1;//0.5+1
#10 A=0;
#10 B=1;
#10 B=0;
#10 B=1;//1+0.5
#10 B=0;
#10 A=1;
#10 A=0;
#10 B=1;//1+1
#10 B=0;
#10 B=1;
#10 B=0;
#10 A=1;//0.5+0.5+1
#10 A=0;
#10 A=1;
#10 A=0;
#10 B=1;
#10 B=0;
#100;
$finish;
end
initial begin
$dumpfile("drink.vcd");
$dumpvars(0,tb_drink);
end
endmodule
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 恒星不见
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果