FPGA 移位运算与乘法

发布时间:2024年01月14日

? 题目:

?????????已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)

?

由题意可知:

? ? ? ? 复位信号高有效,低复位;在inpu_grant上升沿到来时,取一次d的值,并且4个时钟周期取一次;out是将inpu_grant取到的值进行乘1/3/7/8,并且每个时钟周期乘一个。

项目经验:

????????在FPGA中实现乘法器确实需要消耗一定的资源。这包括逻辑门、触发器、乘法器等。不同的乘法器实现方法消耗的资源有所不同。例如,查找表乘法器需要较大的存储空间,但可以减少乘法操作的逻辑门数量;流水线乘法器需要较多的触发器,但可以实现较高的吞吐量。

????????在FPGA的设计中,如果直接将两个数相乘,会占用大量的LUT逻辑资源,而且会减慢硬件的运算速度。因此,在软件设计中两个数的相乘可以直接使用“*”,但在FPGA的设计中,需要采用更复杂的实现方式来处理乘法操作,以节约资源并提高运算速度。

????????总的来说,虽然乘法操作在FPGA中会消耗一定的资源,但通过合理的实现方式,可以有效地利用资源并提高系统的性能和效率。

算法设计:

? ? ? ? 设 a=1;故:

? ? ? ? ? ? ? ? a << 1 = 2 = a * 2 ;

? ? ? ? ? ? ? ? a << 2 = 4 = a * 2*2 = a * 4;? ??

????????????????a << 3 = 8 = a * 2*2*2 = a* 8;

? ? ? ? ? ? ? ? a << 4 = 16 = a * 2*2*2*2 = a*16;

? ? ? ? ? ? 以此类推,乘1/3/7/8,得;

? ? ? ? ? ? ? ? a = a = a * 1;

? ? ? ? ? ? ? ? a = (a << 1) +?a = a * 3;

? ? ? ? ? ? ? ? a = (a << 2) - a = a * 7;

? ? ? ? ? ? ? ? a = a << 2 = a * 8;

?实现代码:

`timescale 1ns/1ns
module multi_sel(
    input  wire clk,       
    input  wire rst,
    input  wire [7:0]d,
    output reg  input_grant,
    output reg [10:0]out
);
reg [1:0]cnt;
reg [7:0]tmp;
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        cnt <= 0;
    end
    else
    begin
        cnt <= cnt + 1;
    end
end

always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        out <= 0;
        input_grant <= 0;
        tmp <= 0;
    end
    else
    begin
        case(cnt)
            0:  begin
                input_grant <= 1;
                out <= d;
                tmp <= d;
            end
            1:  begin
                input_grant <= 0;
                out <= (tmp << 1) + tmp; 
            end
            2:  begin
                input_grant <= 0;
                out <= (tmp << 3) - tmp;
            end
            3:  begin
                input_grant <= 0;
                out <= tmp << 3;
            end
        endcase 
    end
end
endmodule

前仿真代码:

`timescale 1ns / 1ps

module test_sel();
    reg clk;       
    reg rst;
    reg [7:0]d;

always  begin
    clk = 1;
    #10;
    clk = 0;
    #10;
end

initial begin
    rst = 0;
    d = 143;
    #20 
    rst = 1;
    #80 
    d = 7;
    #80 
    d = 6;
    #20 
    d = 128;
    #20 
    d = 129;
end

multi_sel multi_sel_init(
    .clk(clk),      
    .rst(rst),
    .d(d)
);

endmodule

?测试结果:

文章来源:https://blog.csdn.net/weixin_66634995/article/details/135584514
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。