FPGA 移位运算与乘法

  题目:

         已知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

 测试结果:

相关推荐

  1. FPGA乘除运算实现途径

    2024-01-17 04:36:03       14 阅读
  2. C/C++中的整数乘法运算汇编指令MUL和IMUL

    2024-01-17 04:36:03       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-17 04:36:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-17 04:36:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-17 04:36:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-17 04:36:03       20 阅读

热门阅读

  1. FF++数据集下载脚本代码

    2024-01-17 04:36:03       29 阅读
  2. 一些链接汇总,for se/cs students

    2024-01-17 04:36:03       40 阅读
  3. 暴力求解力扣两数之和

    2024-01-17 04:36:03       33 阅读
  4. DNS记录类型介绍(A记录、MX记录、NS记录等)

    2024-01-17 04:36:03       30 阅读
  5. ROS OpenCV ROI

    2024-01-17 04:36:03       25 阅读
  6. Android 13 - Media框架(31)- ACodec(七)

    2024-01-17 04:36:03       35 阅读
  7. 我被领导骂了

    2024-01-17 04:36:03       29 阅读
  8. SpringCloud服务之间Feign调用不会带上请求头header

    2024-01-17 04:36:03       31 阅读
  9. 主键、外键、建表范式、MySQL索引、用户管理

    2024-01-17 04:36:03       29 阅读
  10. 1. FPGA概述

    2024-01-17 04:36:03       25 阅读