夏宇闻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,输出置零。

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