碎碎念:
由于师兄那里有些忙碌,前期算法还没来得及测试,导致FOC项目目前短暂停更一下~
同时Basic Verilog前期部分的代码还是比较简单的,因此也在尝试一天多更!人不能闲下来哇,不是说生命不息奋斗不止么(手动沟头)
目录
1 模块功能
2 模块代码
3 模块思路
4 TestBench与仿真结果
1 模块功能
时钟上升沿或者复位信号下降沿触发,利用乘法加法运算来实现伪随机数的生成。
2 模块代码
// C runtime library random number generator
//
// uses 32 logic cells for DFF/ADD and 8 DSP blocks for the
// 32x18=>32 multiply
module c_rand (clk,rst,reseed,seed_val,out);
input clk,rst,reseed;
input [31:0] seed_val;
output [15:0] out;
wire [15:0] out;
reg [31:0] state;
always @(posedge clk or posedge rst) begin
if (rst) state <= 0;
else begin
if (reseed) state <= seed_val;
else begin
state <= state * 32'h343fd + 32'h269EC3;
end
end
end
assign out = (state >> 16) & 16'h7fff;
endmodule
3 模块思路
这里的思路比较清晰,主要利用state连续的乘法与加法运算,配合右移与按位与的操作,产生out作为伪随机数的结果。
算法上使用了线性同余发生器这种比较经典的伪随机数生成办法,具体算法细节就不作赘述,可以参考超链接中的内容。
这里不理解的地方在于最后的按位与操作,是把最高位进行了清0,不知道是否是为了保持符号位为0,才进行的。
4 TestBench与仿真结果
`timescale 1ns / 1ps
module c_rand_tb();
reg clk;
reg rstn;
reg reseed;
reg [31:0] seed_val;
wire [15:0] out;
parameter half_cycle = 10;
initial
begin
// code that executes only once
// insert code here --> begin
clk = 0;
forever begin
#half_cycle clk = 1;
#half_cycle clk = 0;
end
// --> end
$display("Running testbench");
end
initial
begin
rstn = 0;
#5 rstn = 1;
#10 rstn = 0;
end
initial
begin
seed_val = 32'd65535;
end
initial
begin
reseed = 0;
#25 reseed = 1;
#10 reseed = 0;
end
c_rand c_rand(
.clk(clk),
.rst(rstn),
.reseed(reseed),
.seed_val(seed_val),
.out(out)
);
endmodule
从仿真结果可以看到,每当新的时钟沿到达是,会产生出新的伪随机数。感觉使用起来还是比较方便的。
这就是本期的全部内容啦,如果你喜欢我的文章,不要忘了点赞+收藏+关注,分享给身边的朋友哇~
更多推荐
Verilog:【2】伪随机数生成器(c_rand.v)
发布评论