基于FPGA的素数累加和的计算

基于FPGA的素数累加和的计算

项目简述

这个小项目其实是乐鑫笔试的一道题,感觉很有意思也有一定的难度,所以这里我们实现这个功能,这里注意一下实现功能只是相对于做题而言,并没有进行算法上面的优化。

题目:素数又称质数(在大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除)
a、用任意语言实现10000以内的所有素数之和
b、Verilog实现素数求和器。要求:输入一个小于10000的任意数,输出小于该数的所有素数之和。

本次实验所用到的软硬件环境如下:
1、VIVADO 2019.1
2、Modelsim 10.7
3、MATLAB 2015b

MATLAB代码

因为没有理论知识,只是解题我们直接给出相应的代码供大家学习:

clc;
clear all;

N = 10000;
sum = 2;

for i = 3:N
    flag = 1;
    for j = 2:i-1
        if(mod(i,j) == 0)
            flag = 0;
        end
    end
    if(flag == 1)
        sum = sum + i;
    end
end

当然这里使用MATLAB有些违规,本来打算使用c语言,但是因为c环境还需要重新安装也就没有使用。

Verilog代码

我们直接给出b问题的代码,代码不再多说以为内比较简单,相信大家都可以看懂。
test模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : https://blog.csdn.net/zhangningning1996
// Module Name  : test.v
// Create Time  : 2020-06-08 19:25:24
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************
module test(
    input                   sclk            ,
    input                   rst_n           ,
    input           [13:0]  data            ,
    input                   data_en         ,
    output  reg             ready           ,
    output  reg     [19:0]  sum_data        ,
    output  reg             sum_data_en     
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
reg                 [13:0]  data_r          ;
reg                 [13:0]  cnt_data        ;
reg                 [13:0]  cnt_cnt_data    ;
reg                         flag            ;
wire                [13:0]  mod             ;

 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign      mod             =              cnt_data%cnt_cnt_data; 


always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        data_r              <=              14'd0;
    else if(data_en == 1'b1)
        data_r              <=              data;
    else
        data_r              <=              data_r;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        ready               <=              1'b1;
    else if(data_en == 1'b1)
        ready               <=              1'b0;
    else if(sum_data_en == 1'b1)
        ready               <=              1'b1;
    else
        ready               <=              ready;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        cnt_data            <=              14'd2;
    else if(cnt_data == data_r && (flag == 1'b1 || cnt_cnt_data == cnt_data-1'b1))
        cnt_data            <=              14'd2;
    else if(ready == 1'b0 && mod == 0)
        cnt_data            <=              cnt_data + 1'b1; 
    else if(ready == 1'b0 && cnt_cnt_data == cnt_data-1'b1)
        cnt_data            <=              cnt_data + 1'b1;
    else
        cnt_data            <=              cnt_data;
        

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        cnt_cnt_data        <=              14'd2;
    else if(cnt_cnt_data == cnt_data-1 || flag == 1'b1)
        cnt_cnt_data        <=              14'd2;
    else if(ready == 1'b0)
        cnt_cnt_data        <=              cnt_cnt_data + 1'b1;
    else
        cnt_cnt_data        <=              14'd2;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        flag                <=              1'b0;
    else if(mod == 0)
        flag                <=              1'b1;
    else
        flag                <=              1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        sum_data            <=              20'd2;
    else if(data_en == 1'b1)
        sum_data            <=              20'd2;
    else if(cnt_cnt_data == cnt_data-1)
        sum_data            <=              sum_data + cnt_data;
    else
        sum_data            <=              sum_data;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        sum_data_en         <=              1'b0;
    else if(cnt_data == data_r && (flag == 1'b1 || cnt_cnt_data == cnt_data-1'b1)) 
        sum_data_en         <=              1'b1;
    else
        sum_data_en         <=              1'b0; 

endmodule

为了验证我们实验的正确性,我们进行了测试代码的书写
test_tb模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : https://blog.csdn.net/zhangningning1996
// Module Name  : test_tb.v
// Create Time  : 2020-06-08 19:25:21
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module test_tb();
reg                     sclk                ;
reg                     rst_n               ;
reg                     data_en             ;
wire                    ready               ;
wire            [19:0]  sum_data            ;
wire                    sum_data_en         ;  

initial begin
    sclk            =           1'b0;
    rst_n           <=          1'b0;
    data_en         <=          1'b0;
    #(10000)
    rst_n           <=          1'b1;
    #(10000)
    data_en         <=          1'b1;
    #(10)
    data_en         <=          1'b0;
end

always # 5     sclk         =           ~sclk;
    

test test_inst(
    .sclk            (sclk              ),
    .rst_n           (rst_n             ),
    .data            (1000              ),
    .data_en         (data_en           ),
    .ready           (ready             ),
    .sum_data        (sum_data          ),
    .sum_data_en     (sum_data_en       )
);

endmodule

结果验证

当输入1000时,MATLAB运行的结果如下:
在这里插入图片描述
Modelsim仿真的结果如下:
在这里插入图片描述
经过上面的两个图形从而验证了我们实验的正确性。

总结

创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值