夏宇聞verilog第十章答案_練習六

源碼:

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,輸出置零。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章