項目簡述
這個小項目其實是樂鑫筆試的一道題,感覺很有意思也有一定的難度,所以這裏我們實現這個功能,這裏注意一下實現功能只是相對於做題而言,並沒有進行算法上面的優化。
題目:素數又稱質數(在大於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 : [email protected]
// 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 : [email protected]
// 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仿真的結果如下:
經過上面的兩個圖形從而驗證了我們實驗的正確性。
總結
創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。爲行業貢獻及其微小的一部分。或者對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣: