源碼:
module functions(
a,
b,
clk,
rst,
error,
sel
);
input [15:0] a;
input [1:0] sel;
input clk,rst;
output [47:0] b;//只滿足了立方,階乘可能越界,設置一個錯誤位
output error;
parameter callsquare = 2'd0,callcube = 2'd1,callfactorial = 2'd2;
reg [47:0] b;
reg error;
reg [47:0] factorial0;
integer i;//reg和integer可以相乘,不過integer默認有符號,並且相乘之前不要忘了初始化
reg c;//進位位
always@(posedge clk or negedge rst)
begin
if(rst == 1'b0)
begin
b <= 47'b0;
error <= 1'b0;
factorial0 <= 48'h0000_0000_0000;
c <= 1'b0;
end
else
begin
case(sel)
callsquare: b <= square(a);
callcube: b <= cube(a);
callfactorial: b <= factorial(a);
default:begin b <= 47'b0;error <= 1'b1; end
endcase
end
end
function [47:0] square;
input [15:0] a0;
begin
error = 1'b0;
c = 1'b0;
square = a0*a0;
end
endfunction
function [47:0] cube;
input [15:0] a1;
begin
error = 1'b0;
c = 1'b0;
cube = a1*a1*a1;//函數裏面必須阻塞賦值
end
endfunction
function [47:0] factorial;
input [15:0] a2;
begin
error = 1'b0;
c = 1'b0;
factorial = 48'h0000_0000_0000;
factorial[15:0] = a2;
//不過奇怪的是,這裏一個clk邊沿就就計算出來了,所以邏輯會超級複雜,這樣寫或許一點也不好
for(i = 2;i < a2;i = i + 32'b1)
begin
{c,factorial} = factorial * i;//不過目前必須得設置中間變量,否則無法初始化
if(c == 1'b1) error = 1'b1;
end
if(error == 1'b1)
factorial = 48'hffff_ffff_ffff;
end
endfunction
endmodule
測試代碼:
`timescale 1ns/1ns
module functionstb;
reg [15:0] a;
reg [1:0] sel;
reg clk,rst;
wire [47:0] b;//只滿足了立方,階乘可能越界,設置一個錯誤位
wire error;
initial
begin
sel = 2'b0;
a = 16'd3;
clk = 1'b0;
rst = 1'b1;
#5
rst = 1'b0;
#5
rst = 1'b1;
repeat(16)
begin
#10
sel = sel + 2'b1;
a = a + 16'd1;
end
end
always #1 clk = ~clk;
functions functions0(
.a(a),
.b(b),
.clk(clk),
.rst(rst),
.error(error),
.sel(sel)
);
endmodule
現象:
可見情況1,階乘結果沒有越界,未輸出error,情況2,階乘越界,輸出error且輸出全置一,在選到沒有對應的sel = 3的時候,也是輸出error,輸出置零。