斐波那契数列verilog实现
前言: 该题为睿思芯科笔试题,笔试时长20分钟。
题目描述
用代码实现斐波那契数列,代码需要对对enable敏感,当enable为高几周期,sum在enble为高的下一周期输出第几个斐波那契数,斐波那契数列的生成是后一个数字是前两个数字之和,如下序列:0、1、1、2、3、5、8、13、21、34...,当enable为0时,输出端口sum的值为0
另外,当enable拉高第一周期时,在下一拍输出0,拉高第n个周期,在下一拍输出第n个斐波那契值。
tips:斐波那契数列F(0)=1,这里的F(0)=0是因为笔试题就是这样出的,笔者仅是复述题目并实现,重点在于实现思路。
解题思路
解题的方法就是利用斐波那契数列的特性,用两个寄存器存储斐波那契数列的值,然后在下一周期通过非阻塞赋值更新reg1和reg2的值,并且把二者之和输出给sum。
reg_sum<= reg1+reg2; reg1 <= reg2; reg2 <= reg1+reg2;
还有一个要点,题目要求 enable为0时,sum输出0,所以由于enble和输出的sum是错了一拍的,为了让他们对齐,需要对enble打一拍得到enable_dl。然后根据enable_dl是否为1,确定输出应该为斐波那契值还是0.
代码
module fib_gen( input clk, // positive edge trigger clock input rstn,// active low reset input enable, output [31:0] sum ); reg [31:0] reg1,reg2,reg_sum; reg [31:0] counter; reg enable_dl; always @(posedge clk)begin if(!rstn)begin reg1 <= 32d0; reg2 <= 32d1; reg_sum <= 32d0; end else if(enable )begin if(counter==32d0)begin reg_sum <= 32d0; end else if(counter == 32d1)begin reg1 <= 32d0; reg2 <= 32d1; reg_sum <= 32d1; end else begin reg_sum<= reg1+reg2; reg1 <= reg2; reg2 <= reg1+reg2; end end end always @(posedge clk)begin if(!rstn) counter <= 32d0; else if(enable)begin counter <= counter + 1b1; end end always @(posedge clk)begin if(!rstn) enable_dl<= 1d0; else enable_dl <= enable; end assign sum = enable_dl ? reg_sum:0; endmodule
testbench
module tb(); reg clk, rstn,enable; wire [31:0 ]sum; initial begin forever #5 clk = ~clk; end initial begin rstn = 1b0; clk = 1b1; enable = #1 1b0; #10 rstn = #1 1b1; #10 enable = #1 1b1; #100 $finish(); end fibonacci u_fibonacci( .clk (clk ), .rstn (rstn ), .enable (enable ), .sum (sum ) ); initial begin $fsdbDumpfile("fibonacci.fsdb"); $fsdbDumpvars(0); end endmodule