【数电实验】随机数生成电路

一、设计任务要求

  1. 1. 设计并实现一个随机数生成电路,每 2 秒 随机生成一个 0~999 之间的数 字,并在数码管上显示生成的随机数。
  2. 2. 为系统设置一个复位键,复位后数码管显示“000”,2 秒后再开始每 2 秒 生成并显示随机数,要求使用按键复位。
  3. 3. 实验板上输入时钟选择 1kHz 或更高的频率。
  4. 二、设计思路

随机数产生:设一个变量f为vector(5 downto 0),随时钟进行计数,其中的,每次抽取其中四位进行相邻位异或运算产生新的数作为这一位数。

如第一个数的有四位,则取f的0~3位,第二个数,则取f的1~4位,第三个数,则取f的2~5位。

第一位数有四位,如第一位数的第0位,则为从取出来的f的0~3位的第0位和第1位异或,第1位,则为从f中取出来的第1位和第2位异或,第2位则为从f中取出来的第2位和第3位异或,第三位则为第3位和第0位异或;第二位数有四位,第0位,则为从取出来的f的1~4位的,第1位和第2位异或,第1位,则为从f中取出来的第2位和第3位异或,第2位则为从f中取出来的第3位和第4位异或,第三位则为第4位和第1位异或;其他以此类推产生随机数。

在译码电路通过对译码电路的的10~15进行赋值0~9,使得16个数都有对应的值。

2.1总体电路为:

输入信号1kHz,对时钟信号进行2000分频,使得数码管能保持2秒不变,通过随机数产生后,通过译码电路,使用时钟频率1kHz进行扫描,使三个数码管交替变亮让肉眼觉得是三个同时亮。

2.2模块划分

 2.3总体框图

三、VHDL代码

 3.1 2000分频模块

library ieee;                                    --库和程序包声明
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity div2000 is                               --2000分频器实体描述
	port(
		clk: in std_logic;                        --时钟输入端口
		clear: in std_logic;                     --复位键输入端口
		clk_out:out std_logic);                  --时钟分频后输出端口
end div2000;

architecture a of div2000 is                    --结构体描述
	signal tmp: integer range 0 to 999; --整型数,用来记录分频
	signal clktmp: std_logic;          --信号定义,只能是储存时钟信号
begin
	process(clear,clk)
	begin
		if clear='1' then  --如果按下复位键,分频计数归零,重新开始计数
			tmp<=0;
		elsif clk'event and clk='1' then
			if tmp=999 then           --从0计数到999,则信号反转一下
				tmp<=0;clktmp<=not clktmp;
		else
			tmp<=tmp+1;
		end if;
	end if;
end process;
clk_out<=clktmp;
end a;

3.2 防抖模块

此防抖电路为计数型防抖电路。人按动按钮时,相对于高速的时钟频率来说很慢,而抖动则很快,可以通过计数来消除抖动,当按动持续一定时间,则输出正脉冲;若持续时间过短,则为抖动不进行输出。

library ieee;                                     --库和程序包声明
use ieee.std_logic_1164.all;

entity antisk is                                --防抖电路实体描述
	port(clk:in std_logic;                      --时钟信号
		 input:in std_logic;                     --按钮输入端口
		 output:out std_logic                   --输出端口
		 );
end antisk;

architecture a of antisk is
	signal a:std_logic;
	signal count:integer range 0 to 9;
begin
	process(clk)
	begin
		if input='0' then
		  count<=0;
		elsif (clk'event and clk='1') then              --当按钮输入时
		  if count=9 then                     --当按钮按动持续一定时间
		    count<=count;
		  else count<=count+1;
		  end if;
		end if;
		
		if count=8 then a<='1';                --则输出为正
		else a<='0';
		end if;
	end process;
 output<=a;
end;

3.3 随机数生成模块

使用时钟频率1KHz进行三个数码管扫描输出,使人眼以为同时亮。

因为每一个三位的随机数要保持2秒,所以产生的随机数只要2秒变一回就可以。产生随机数的思路是,设一个6位向量,三个数,每一个是4位的向量,从6位向量里面依次取出4位,然后四位进行异或运算,得出新的四位数作为输出。

library ieee;                                   --库和程序包
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity random is
port (clk1000:in std_logic;                       --时钟输入1KHz
	  clk2:in std_logic;                           --时钟输入0.5Hz
	  clear:in std_logic;                           --复位
	 f1_out:std_logic_vector(3 downto 0); --第一个随机数(为了波形能看到)
     f2_out:std_logic_vector(3 downto 0); --第二个随机数(为了波形能看到)
     f3_out:std_logic_vector(3 downto 0); --第三个随机数(为了波形能看到)
	  shu:out std_logic_vector(3 downto 0);--送给译码电路译码
	  cat:out std_logic_vector(7 downto 0));--数码管亮还是不亮控制
end entity;

architecture a of random is
signal tmp:integer range 0 to 2;         --用来循环让三个数码管依次亮起
signal f:std_logic_vector(5 downto 0);       --计数增加
signal f0:std_logic_vector(5 downto 0); --从f中取数,供以产生三个随机数
signal f1:std_logic_vector(3 downto 0);      --第一个随机数
signal f2:std_logic_vector(3 downto 0);      --第一个随机数
signal f3:std_logic_vector(3 downto 0);      --第一个随机数

begin 
   process(clk1000,clk2,clear)     --开始进程,以时钟clk1000,
begin                          --和时钟clk2,复位清除clear为敏感信号
if (clk2'event and clk2='1') then f<=f+3; end if;   --f每2秒变一回

if clear='1' then f0<="000000";            --当复位信号来了,f0赋值为0
    elsif (clk2'event and clk2='1') then    --如果复位信号没有来,每两秒
     f0<=f;                               --将f的值赋给f0
     end if;      
    
f1(0)<=f0(0) xor f0(1);   --第一位数的第0位是f0的第0位与第1位异或
f1(1)<=f0(1) xor f0(2);   --第一位数的第1位是f0的第1位与第2位异或
f1(2)<=f0(2) xor f0(3);   --第一位数的第2位是f0的第2位与第3位异或
f1(3)<=f0(3) xor f0(0);   --第一位数的第3位是f0的第3位与第0位异或
    
f2(0)<=f0(1) xor f0(2);   --第二位数的第0位是f0的第1位与第2位异或
f2(1)<=f0(2) xor f0(3);   --第二位数的第0位是f0的第2位与第3位异或 
f2(2)<=f0(3) xor f0(4);   --第二位数的第0位是f0的第3位与第4位异或 
f2(3)<=f0(4) xor f0(1);   --第二位数的第0位是f0的第4位与第1位异或 
    
f3(0)<=f0(2) xor f1(3);   --第三位数的第0位是f0的第2位与第3位异或 
f3(1)<=f0(3) xor f0(4);   --第三位数的第1位是f0的第3位与第4位异或 
f3(2)<=f0(4) xor f0(5);   --第三位数的第2位是f0的第4位与第5位异或 
f3(0)<=f0(5) xor f0(2);   --第三位数的第3位是f0的第5位与第2位异或
    
if (clk1000'event and clk1000='1') then  --用来判断刷新三个数码管
       if tmp=2 then tmp<=0 ;else tmp<=tmp+1;--刷新的频率大于50Hz
     end if;end if;                           --人眼看到就不会抖动
    
    case tmp is
     when 0=> shu<=f1;cat<="11110111";    --tmp=0,第3个数码管亮
     when 1=> shu<=f2;cat<="11111011";    --tmp=1,第2个数码管亮
     when 2=> shu<=f3;cat<="11111101";    --tmp=2,第1个数码管亮
end case;

f1_out<=f1;f2_out<=f2;f3_out<=f3;     --看最后总体的输出波形使用
   end process;
   
 end;

3.4 数码管译码电路

由于一个数码管只能显示数字0~9,而四位二进制数能显示0~15,所以对于超过10的数进行重新赋值显示

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY seg IS
	PORT(
		a:IN STD_LOGIC_VECTOR(3 DOWNTO 0);    --输入端口
		b:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));  --输出端口
	END seg;
	
ARCHITECTURE seg7_1_arch OF seg IS
BEGIN

	PROCESS(a)
	BEGIN
		CASE a IS
			WHEN "0000" => b <= "1111110";  --输入是0,则显示0
			WHEN "0001" => b <= "0110000";  --输入是1,则显示1
			WHEN "0010" => b <= "1101101";  --输入是2,则显示2
			WHEN "0011" => b <= "1111001";  --输入是3,则显示3
			WHEN "0100" => b <= "0110011";  --输入是4,则显示4
			WHEN "0101" => b <= "1011011";  --输入是5,则显示5
			WHEN "0110" => b <= "1011111";  --输入是6,则显示6
			WHEN "0111" => b <= "1110000";  --输入是7,则显示7
			WHEN "1000" => b <= "1111111";  --输入是8,则显示8
			WHEN "1001" => b <= "1111011";  --输入是9,则显示9
			
			WHEN "1010" => b <= "1110000"; --输入是10,则显示7
			WHEN "1011" => b <= "0110000"; --输入是11,则显示1
			WHEN "1100" => b <= "0110011"; --输入是12,则显示4
			WHEN "1101" => b <= "1111111"; --输入是13,则显示8
			WHEN "1110" => b <= "1011111"; --输入是14,则显示6
			WHEN "1111" => b <= "1111110"; --输入是15,则显示0
		END CASE;
	END PROCESS;
END;

3.5 总体电路连接模块

library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
 use ieee.std_logic_arith.all;
 entity whole is
 port (clock,key:in std_logic;             --时钟和复位信号
            seg0:out std_logic_vector(6 downto 0); --数码管
            shu:out std_logic_vector(3 downto 0); --数码管此时译码的数
f1:out std_logic_vector(3 downto 0); --第一个随机数(为了波形看见)
      f2:out std_logic_vector(3 downto 0); --第一个随机数(为了波形看见)
      f3:out std_logic_vector(3 downto 0); --第一个随机数(为了波形看见)
            cat0:out std_logic_vector(7 downto 0));--数码管显示控制
end entity whole;

architecture a of whole is
   component div2000                        --2000分频器组件声明
   port(
		clk: in std_logic;
		clear: in std_logic;
		clk_out:out std_logic);
end component;

     component random                         --随机数组件声明
     port (
	  clk1000:in std_logic;
	  clk2:in std_logic;
	  clear:in std_logic;
	  f1_out:out std_logic_vector(3 downto 0);
      f2_out:out std_logic_vector(3 downto 0);
      f3_out:out std_logic_vector(3 downto 0);
	  shu:out std_logic_vector(3 downto 0);
	  cat:out std_logic_vector(7 downto 0));
end component;
    
component antisk                              --防抖电路组件声明
    port(clk:in std_logic;
		 input:in std_logic;
		 output:out std_logic);
end component;

    component seg                            --译码电路组件声明
    port (
		a:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
		b:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
	END component;

signal clea,cp1000,cp2:std_logic;
signal yi:std_logic_vector(3 downto 0);

begin                                             --电路连接
shu<=yi;
u1:div2000 port map (clk=>clock,clear=>clea,clk_out=>cp2);
u2:antisk port map(clk=>clock,input=>key,output=>clea);
u3:random
port map
(clk1000=>clock,clk2=>cp2,clear=>clea,cat=>cat0,shu=>yi,f1_out=>f1,f2_out=>f2,f3_out=>f3);
u4:seg port map (a=>yi,b=>seg0);
end;

四、仿真波形分析

4.1 2000分频器

图1

 图2

 图3

 图4

 仿真波形分析:

如图所示,图1为整体波形,图2为图1的第一个上升沿到来时的放大图,图3是图1的第一个下降沿到来时的放大图,图4是图一的clear复位信号部分的放大图。

由图2和图3可知,每当计数信号tmp从0计数到999时,输出信号就进行一次反转,总体一个周期就是从0计数到1999进行一次反转,即把输入信号进行了2000分频,且占空比为50%。

由图4可知当复位信号出现时,计数信号tmp马上异步清零,重新开始计数。所以,clear为异步复位键。

4.2 防抖电路模块

 图1

 图2

仿真波形分析:

如图所示,图1为整体仿真波形图,前面较为宽的模拟人手按下按键,后面较为窄的表示机械按键的抖动。图1共表示了按键按动了4次;图2为第一次按键的放大图。

图2,当没有按键时,即input一直是低电平,则计数信号count的值一直是0,当由按键信号时,且持续时间按足够长,即计数信号计数到8时,输出信号output才输出高电平,当计数信号持续时间不够长,即后面产生的毛刺,则输出信号不进行高电平输出。由此,不带有毛刺的输出波形进行了防抖动。

4.3 随机数生成模块

 图1

 图2

 图3

仿真波形分析:

如图所示,图1为整体波形仿真,输出信号随clk2每两秒变一回,送给译码电路的信号shu和控制哪个数码管亮的信号cat变化速度很快,随clk1000进行变化.

图2图1的clk2的第二个上升沿到来时的放大图。由图可知,此时的f1=10,f2=9,f3=0.cat和送给译码电路的shu在f1、f2、f3之间循环切换输出。

图3是图1的复位信号clear到来时的放大图。复位信号到来,此时f0马上转换为0,相应的f1、f2、f3都转换为零。而且转换的时间不是在时钟上升沿到来的时候,是随复位信号出现而进行转变,则可以说明,复位信号是异步复位的。

4.4 译码电路模块

 仿真波形分析:

如图所示,当给输入信号a不同的值,则输出信号会有不同的译码输出。b的输出是按照数码管的a、b、c、d、e、f、g进行译码输出。当a的值超过9后,10的译码输出和7一样,11的译码输出和1一样,12的译码输出和4一样,13的译码输出和8一样,14的译码输出和6一样,15的译码输出和0一样。这样,无论前面随机出传进来的数是多少,最后的译码电路总能译出一个数。

4.5 电路综合

 图1

 图2

仿真波形分析:

如图所示,图1生成的随机信号f1、f2、f3、每两秒变一回,当复位信号key按动时,则f1、f2、f3马上变回0,且能持续两秒,还能说明key是异步信号。

图2为clktmp的第二个上升沿附近的放大图。由图可知,随着clk1000的变化,shu 在f1、f2、f3之间安来回切换,cat0也是与之相对应的切换,告诉变化可以达到迷惑人眼的效果,这样就能最终达到人眼看到的是3个数码管同时亮。

五、故障及问题分析

  1. 最后电路综合仿真的时候,想要出现的引脚没有。解决方法,最后加上一个输出引脚,这样最后的仿真波形的选项最后就能出现所要选择的。
  2. 随机数生成电路,最开始设计的时候一按复位键,然后出现的数字都是固定的。要解决这样的问题,可以把计数信号,和给最后的进行运算变换的信号分开,这样即使运算变换的信号变为0,计数信号不是0,这样最后就能达到复位之后,下一个数字不是0的效果。
  3. 译码的时候要考虑到二进制和十进制之间的区别,把所有的情况都考虑一遍,就是把10~15的情况思考清楚。

六、总结

随机数产生,用电路做出来的最终结果都是伪随机,当时间足够长的时候都会进行循环。

到由多个时钟信号输入进来的时候,要有清晰的认识,那个时钟是干什么的,否则会产生很多冗余的代码。且一个信号的最后决定它变化的只能有一个,不能同时多个判断,这样编译会不通过。

  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
随机数作为密钥或密码运算资源被广泛应用于信息安全系统,随机数的研究 越来越重要。随着计算技术和密码学的发展,在信息安全应用中不仅需要可输出 各种形式随机数的发生器,而且还需要对随机数的随机性做更深入的研究与分析, 为相关应用提供理论支撑。 本文综合讨论了随机数发生器及随机性检测器的设计与实现。 首先对随机数发生器进行了分类讨论,按照真随机数发生器与伪随机数发生 器两种产生方法及性能进行了分析和对比。本文研究并设计了两款伪随机数发生 器,并用软件实现这两个发生器,产生相应的实例以供随机性检测器测试。同时 在信息安全领域真 随机数发生器中选择了一款常用的噪声源芯片 WNG4 ,用该芯 片产生真随机数,本软件系统调用该真随机数序列作为测试实例,以供随机性检 测器测试。 其次 本文设计并实现了一款随机性检测器,该检测器实现了国内较常用的 15 种检测方法,包括单比特频数检测、块内频数检测、扑克检测、重叠子序列检测、 游程总数检测、游程分布检测、块内最 大 1 游程检测、二元推导检测、自相关 检测 、矩阵秩检测、累加和检测、近似熵检测、线性复杂度检测、 Maurer 通用统 计检测、离散傅立叶检测等 15 项检测方法。以统计与概率学为理论依据,对 15 种检测方法进行 软件实现,对每种方法的运算步骤及实现做了详细的研究与分析。 然后 本文使用三个正向实例与一个反向实例作为测试案例对检测器进行测试。 正向实例为本文自行设计 的 随机数发生器产生 的 结果 作 为待测样本数据 即两款 伪随机数发生器与一款真随机数发生器产生的随机数 。 反向实例为模拟一个有明 显缺陷的随机数序列。 本文 详细讨论了测试结果,对随机数发生器与随机性检测 器同时进行测试与验证, 以 证明随机数发生器的良好性能及随机性检测器的运行 有效性,并得出结论, 证明 该检测系统的设计与实现与预期一致。 本文的亮点在于: 紧密结合工作实际,紧紧围 绕随机数随机性检测这一课题的研究,系统地梳 理了相关检测方法,综合国内实际情况选择了最适合信息安全领域的 15 种检测方 法,再用简洁高效的软件语言实现这些检测方法,拓展了企业在随机性检测领域 的检测能力,使之成为信息安全 领域 的有效测试工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值