Verilog ----基礎5
【例8.1】$time 與$realtime 的區別
`timescale 10ns/1ns
module time_dif;
reg ts;
parameter delay=2.6;
initial
begin
#delay ts=1;
#delay ts=0;
#delay ts=1;
#delay ts=0;
end
initial
$monitor($time,,,"ts=%b",ts);
//使用函數$time
endmodule
【例8.2】$random 函數的使用
`timescale 10ns/1ns
module random_tp;
integer data;
integer i;
parameter delay=10;
initial
$monitor($time,,,"data=%b",data);
initial begin
for (i=0; i<=100; i=i+1)
#delay data=$random; //每次產生一個亂數
end
endmodule
【例8.3 】1 位全加器進位輸出UDP 元件
primitive
carry_udp(cout,cin,a,b);
input cin,a,b;
output cout;
table
//cin
a b :
cout //真值表
0
0 0 :
0;
0
1 0 :
0;
0
0 1 :
0;
0
1 1 :
1;
1
0 0 :
0;
1
0 1 :
1;
1 1 0
: 1;
1
1 1 :
1;
endtable
endprimitive
【例8.4 】包含x 態輸入的 1 位全加器進位輸出UDP 元件
primitive
carry_udpx1(cout,cin,a,b);
input cin,a,b;
output cout;
table
// cin a
b : cout
//真值表
0
0 0 :
0;
0
0 1 :
0;
0 1
0 : 0;
0 1
1 : 1;
1 0
0 : 0;
1 0
1 : 1;
1
1 0 :
1;
1 1
1 : 1;
0 0
x : 0;
//只要有兩個輸入為0,則進位輸出肯定為0
0 x
0 : 0;
x 0
0 : 0;
1 1
x : 1;
//只要有兩個輸入為1,則進位輸出肯定為1
1 x
1 : 1;
x 1
1 : 1;
endtable
endprimitive
【例8.5 】用簡縮符“?”表述的1 位全加器進位輸出UDP 元件
primitive carry_udpx2(cout,cin,a,b);
input
cin,a,b;
output cout;
table
// cin
a b :
cout //真值表
?
0 0 :
0;
//只要有兩個輸入為0,則進位輸出肯定為0
0
? 0 :
0;
0
0 ? :
0;
?
1 1 :
1;
//只要有兩個輸入為1,則進位輸出肯定為1
1
? 1 :
1;
1
1 ? :
1;
endtable
endprimitive
【例8.6 】3 選 1 多路選擇器UDP 元件
primitive mux31(Y,in0,in1,in2,s2,s1);
input in0,in1,in2,s2,s1;
output Y;
table
//in0
in 1 in 2 s2 s1 :
Y
0
? ? 0
0 : 0;
//當s2s1=00 時,Y=in0
1
? ? 0
0 : 1;
?
0 ? 0
1 : 0;
//當s2s1=01 時,Y=in1
?
1 ? 0
1 : 1;
?
? 0 1
? : 0;
//當s2s1=1?時,Y=in2
?
? 1 1
? : 1;
0
0 ? 0
? : 0;
1
1 ? 0
? : 1;
0 ? 0
? 0 :
0;
1 ? 1 ?
0 : 1;
?
0 0 ?
1 : 0;
? 1 1
? 1 :
1;
endtable
endprimitive
【例8.7 】電平敏感的1 位元資料鎖存器UDP
元件
primitive
latch(Q,clk,reset,D);
input
clk,reset,D;
output Q;
reg Q;
initial Q =
1'b1; //初始化
table
// clk reset D : state : Q
?
1 ? : ? :
0 ;
//reset=1,則不管其他埠為什麼值,輸出都為0
0
0 0 : ? :
0 ;
//clk=0,鎖存器把D 端的輸入值輸出
0
0 1 : ? :
1 ;
1
0 ? : ? : - ;
//clk=1,鎖存器的輸出保持原值,用符號“-”表示
endtable
endprimitive
【例8.8】上升沿觸發的D 觸發器UDP 元件
primitive DFF
(Q,D,clk);
output Q;
input D,clk;
reg Q;
table
//clk
D : state : Q
(01)
0 : ? : 0;
//上升沿到來,輸出Q=D
(01)
1 : ? : 1;
(0x)
1 : 1 : 1;
(0x)
0 : 0 : 0;
(?0)
? : ? : -;
//沒有上升沿到來,輸出Q 保持原值
?
(??) : ? : - ;
//時鐘不變,輸出也不變
endtable
endprimitive
【例8.9 】帶非同步置1 和非同步清零的上升沿觸發的D 觸發器UDP
元件
primitive DFF_UDP (Q,D,clk,clr,set);
output Q;
input D,clk,clr,set;
reg Q;
table
// clk D
clr set : state : Q
(01) 1
0 0 : ? :
0;
(01) 1
0 x : ? :
0;
? ?
0 x : 0 :
0;
(01) 0
0 0 : ? :
1;
(01) 0
x 0 : ? :
1;
? ?
x 0 : 1 :
1;
(x1) 1
0 0 : 0 :
0;
(x1) 0
0 0 : 1 :
1;
(0x) 1
0 0 : 0 :
0;
(0x) 0
0 0 : 1 :
1;
? ?
1 ? : ? :
1; //非同步重定
? ?
0 1 : ? :
0; //非同步置1
n ?
0 0 : ? :
-;
? *
? ? : ? :
-;
? ?
(?0) ? : ? : -;
? ?
? (?0): ? : -;
? ?
? ? :
? : x;
endtable
endprimitive
【例8.12】延遲定義塊舉例
module delay(out,a,b,c);
output out;
input a,b,c;
and a1(n1,a,b);
or o1(out,c,n1);
specify
(a=>out)=2;
(b=>out)=3;
(c=>out)=1;
endspecify
endmodule
【例8.13】激勵波形的描述
'timescale 1ns/1ns
module test1;
reg A,B,C;
initial
begin //激勵波形描述
A = 0; B = 1; C = 0;
#100 C = 1;
#100 A = 1; B = 0;
#100 A = 0;
#100 C = 0;
#100 $finish;
end
initial
$monitor($time,,,"A=%d B=%d C=%d",A,B,C); //顯示
endmodule
【例8.15】用always 過程塊產生兩個時鐘信號
module test2;
reg clk1,clk2;
parameter CYCLE = 100;
always
begin
{clk1,clk2} = 2'b10;
#(CYCLE/4) {clk1,clk2} = 2'b01;
#(CYCLE/4) {clk1,clk2} = 2'b11;
#(CYCLE/4) {clk1,clk2} = 2'b00;
#(CYCLE/4) {clk1,clk2} = 2'b10;
end
initial $monitor($time,,,"clk1=%b
clk2=%b",clk1,clk2);
endmodule
【例8.17】記憶體在仿真程式中的應用
module
ROM(addr,data,oe);
output [7:0]
data; //資料信號
input [14:0]
addr; //位址信號
input oe; //讀使能信號,低電平有效
reg [7:0] mem[0:255]; //記憶體定義
parameter DELAY = 100;
assign #DELAY data=(oe==0) ? mem[addr] :
8'hzz;
initial $readmemh
("rom.hex",mem); //從檔中讀入資料
endmodule
【例8.18】8 位元乘法器的仿真程式
`timescale 10ns/1ns
module mult_tp; //測試模組的名字
reg [7:0] a,b; //測試輸入信號定義為reg 型
wire [15:0] out; //測試輸出信號定義為wire 型
integer i,j;
mult8
m 1(out,a,b);
//調用測試物件
//激勵波形設定
initial
begin
a=0;b=0;
for (i=1;i<255;i=i+1)
#10 a =i;
end
initial
begin
for (j=1;j<255;j=j+1)
#10 b=j;
end
initial //定義結果顯示格式
begin
$monitor($time,,,"%d * %d=
%d",a,b,out);
#2560 $finish;
end
endmodule
module mult8(out, a, b); //8位乘法器源代碼
parameter size=8;
input [size:1] a,b; //兩個運算元
output [2*size:1] out; //結果
assign out=a*b; //乘法運算符
endmodule
【例8.19】8 位元加法器的仿真程式
`timescale
1ns/1ns
module
add8_tp; //仿真模組無埠列表
reg [7:0] A,B; //輸入激勵信號定義為reg 型
reg cin;
wire [7:0]
SUM; //輸出信號定義為wire 型
wire cout;
parameter DELY =
100;
add8
AD1(SUM,cout,A,B,cin);
//調用測試物件
initial begin //激勵波形設定
A= 8'd0; B= 8'd0; cin=1'b0;
#DELY A= 8'd100;
B= 8'd200; cin=1'b1;
#DELY A= 8'd200;
B= 8'd88;
#DELY A= 8'd210;
B= 8'd18; cin=1'b0;
#DELY A= 8'd12;
B= 8'd12;
#DELY A= 8'd100;
B= 8'd154;
#DELY A= 8'd255;
B= 8'd255; cin=1'b1;
#DELY $finish;
end
//輸出格式定義
initial
$monitor($time,,,"%d + %d + %b = {%b, %d}",A,B,cin,cout,SUM);
endmodule
module
add8(SUM,cout,A,B,cin); //待測試的8位元加法器模組
output [7:0]
SUM;
output cout;
input [7:0]
A,B;
input cin;
assign
{cout,SUM}=A+B+cin;
endmodule
【例8.20 】2 選 1 多路選擇器的仿真
`timescale
1ns/1ns
module mux_tp;
reg a,b,sel;
wire out;
MUX2_1
m 1(out,a,b,sel); //調用待測試模組
initial
begin
a=1'b0; b=1'b0; sel=1'b0;
#5
sel=1'b1;
#5 a =1'b1; sel=1'b0;
#5
sel=1'b1;
#5 a =1'b0; b=1'b1; sel=1'b0;
#5
sel=1'b1;
#5 a =1'b1; b=1'b1;
sel=1'b0;
#5
sel=1'b1;
end
initial $monitor($time,,,"a=%b b=%b
sel=%b out=%b",a,b,sel,out);
endmodule
module MUX2_1(out,a,b,sel); //待測試的2選1MUX模組
input a,b,sel;
output out;
not #(0.4,0.3) (sel_,sel); //#(0.4,0.3)為門延時
and #(0.7,0.6) (a1,a,sel_);
and #(0.7,0.6) (a2,b,sel);
or #(0.7,0.6) (out,a1,a2);
endmodule
【例8.21 】8 位計數器的仿真
`timescale 10ns/1ns
module count8_tp;
reg clk,reset; //輸入激勵信號定義為reg 型
wire [7:0] qout; //輸出信號定義為wire 型
parameter DELY=100;
counter
C1 (qout,reset,clk);
//調用測試物件
always #(DELY/2) clk = ~clk; //產生時鐘波形
initial
begin //激勵波形定義
clk =0; reset=0;
#DELY
reset=1;
#DELY
reset=0;
#(DELY*300)
$finish;
end
//結果顯示
initial
$monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout);
endmodule
module
counter(qout,reset,clk); //待測試的 8位元計數器模組
output [7:0] qout;
input
clk,reset;
reg [7:0]
qout;
always @(posedge
clk)
begin
if (reset) qout<=0;
else qout<=qout+1;
end
endmodule
沒有留言:
張貼留言