Verilog ----基礎3
【例6.1】加法計數器中的進程
module
count(data,clk,reset,load,cout,qout);
output cout;
output [3:0] qout;
reg [3:0] qout;
input [3:0] data;
input clk,reset,load;
always @(posedge clk) //進程 1,always 過程塊
begin
if (!reset) qout= 4'h00; //同步清0,低電平有效
else if (load) qout= data; //同步預置
else qout=qout + 1; //加法計數
end
assign cout=(qout==4'hf)?1:0; //進程2,用持續賦值產生進位元信號
endmodule
【例6.2 】任務舉例
module alutask(code,a,b,c);
input [1:0] code;
input [3:0] a,b;
output [4:0] c;
reg [4:0] c;
task my_and; //任務定義,注意無埠列表
input [3:0] a,b; //a,b,out名稱的作用域範圍為task任務內部
output [4:0] out;
integer i;
begin
for (i=3;i>=0;i=i-1)
out[i]=a[i]&b[i]; //按位與
end
endtask
always@(code or a or b)
begin
case (code)
2'b00: my_and(a,b,c);
/* 調用任務my_and,需注意埠列表的順序應與任務定義中的一致,這裏的a,b,c 分別對應任務定義中的a,b,out */
2'b01: c=a|b; //或
2'b10: c=a-b; //相減
2'b11: c=a+b; //相加
endcase
end
endmodule
【例6.3 】測試程式
`include "alutask.v"
module alu_tp;
reg [3:0] a,b;
reg [1:0] code;
wire [4:0] c;
parameter DELY = 100;
alutask ADD(code,a,b,c); //調用被測試模組
initial begin
code=4'd0; a= 4'b0000; b= 4'b1111;
#DELY
code=4'd0; a= 4'b0111; b= 4'b1101;
#DELY
code=4'd1; a= 4'b0001; b= 4'b0011;
#DELY
code=4'd2; a= 4'b1001; b= 4'b0011;
#DELY
code=4'd3; a= 4'b0011; b= 4'b0001;
#DELY
code=4'd3; a= 4'b0111; b= 4'b1001;
#DELY
$finish;
end
initial $monitor($time,,,"code=%b a=%b
b=%b c=%b", code,a,b,c);
endmodule
【例6.4 】函數
function[7:0] get0;
input [7:0] x;
reg [7:0] count;
integer i;
begin
count=0;
for (i=0;i<=7;i=i+1)
if
(x[i]=1'b0) count=count+1;
get0=count;
end
endfunction
【例6.5 】用函數和case 語句描述的編碼器 (不含優先順序)
module code_83(din,dout);
input [7:0] din;
output [2:0] dout;
function[2:0] code; //函數定義
input [7:0] din; //函數只有輸入,輸出為函數名本身
casex (din)
8'b1xxx_xxxx : code = 3'h7;
8'b01xx_xxxx : code = 3'h6;
8'b001x_xxxx : code = 3'h5;
8'b0001_xxxx : code = 3'h4;
8'b0000_1xxx : code = 3'h3;
8'b0000_01xx : code = 3'h2;
8'b0000_001x : code = 3'h1;
8'b0000_000x : code = 3'h0;
default: code = 3'hx;
endcase
endfunction
assign dout = code(din) ; //函數調用
endmodule
【例6.6 】階乘運算函數
module funct(clk,n,result,reset);
output [31:0] result;
input [3:0] n;
input reset,clk;
reg [31:0] result;
always @(posedge clk) //在clk 的上升沿時執行運算
begin
if (!reset) result<=0; //復位
else
begin
result <= 2 *
factorial(n); //調用factorial 函數
end
end
function[31:0] factorial; //階乘運算函數定義(注意無埠列表)
input [3:0] opa; //函數只能定義輸入端,輸出埠為函數名本身
reg [3:0] i;
begin
factorial = opa ? 1 : 0;
for (i= 2; i <= opa; i = i+1)
//該句若要綜合通過,opa應賦具體的數值
factorial = i* factorial; //階乘運算
end
endfunction
endmodule
【例6.7 】測試程式
`define clk_cycle 50
`include "funct.v"
module funct_tp;
reg [3:0] n;
reg reset,clk;
wire [31:0] result;
initial //定義激勵向量
begin
n=0;
reset=1; clk=0;
for (n=0;n<=15;n=n+1)
#100 n=n;
end
initial $monitor($time,,,"n=%d
result=%d",n,result);
//定義輸出顯示格式
always
# `clk_cycle clk=~clk; //產生時鐘信號
funct funct_try
(.clk(clk),.n(n),.result(result),.reset(reset));
//調用被測試模組
endmodule
【例6.8】順序執行模組1
module serial1(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)
begin
q=~q;
a=~q;
end
endmodule
【例6.9 】順序執行模組2
module serial2(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)
begin
a=~q;
q=~q;
end
endmodule
【例6.10】並行執行模組1
module paral1(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)
begin
q=~q;
end
always @(posedge clk)
begin
a=~q;
end
endmodule
【例6.11】並行執行模組2
module paral2(q,a,clk);
output q,a;
input clk;
reg q,a;
always @(posedge clk)
begin
a=~q;
end
always @(posedge clk)
begin
q=~q;
end
endmodule
沒有留言:
張貼留言