项目简述
这个小项目其实是乐鑫笔试的一道题,感觉很有意思也有一定的难度,所以这里我们实现这个功能,这里注意一下实现功能只是相对于做题而言,并没有进行算法上面的优化。
题目:素数又称质数(在大于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仿真的结果如下:
经过上面的两个图形从而验证了我们实验的正确性。
总结
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: