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

这篇具有很好参考价值的文章主要介绍了【数电实验】随机数生成电路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、设计任务要求

  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的情况思考清楚。

六、总结

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

到由多个时钟信号输入进来的时候,要有清晰的认识,那个时钟是干什么的,否则会产生很多冗余的代码。且一个信号的最后决定它变化的只能有一个,不能同时多个判断,这样编译会不通过。文章来源地址https://www.toymoban.com/news/detail-475253.html

到了这里,关于【数电实验】随机数生成电路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter 生成随机数

    如何让随机数变化? 我们尝试过的都知道,当你创建出来一个随机数后,调用他他的值是随机的,但是,这时候他的值就会固定住,不管怎么样都是随机出来的那个数,如果想要他每次都不一样的话,我们就想要使用刷新来让他变化了。 我们可以使用这样的方法来使他每次不一

    2024年02月13日
    浏览(48)
  • haiku生成随机数

    Haiku 遵循 JAX 的设计,生成的随机数是两个元素组成的列表。其中第一个元素是用于生成伪随机数的状态,第二个元素是用于分发密钥的子键。两个元素分别用于状态和子键,确保在分布式计算或并行计算中,多个随机数生成器的状态可以在一定程度上相互影响,从而提高随

    2024年01月20日
    浏览(65)
  • Hutool 生成随机数和随机字符串

    官方文档: https://www.hutool.cn/docs/#/core/工具类/随机工具-RandomUtil 整理完毕,完结撒花~

    2024年02月16日
    浏览(58)
  • 生成随机数——C语言

    在C语言中,可以使用标准库函数 rand() 来生成随机数。需要注意的是, rand() 函数生成的是伪随机数,具体的随机序列取决于种子(seed)的值。 下面是一个简单的示例代码,展示如何在C语言中生成随机数: 在上述代码中,首先包含了 stdio.h 、 stdlib.h 和 time.h 头文件来使用相

    2024年02月12日
    浏览(55)
  • rust怎么生成随机数?

    在 Rust 中,有几种不同的方法可以实现随机数生成。以下是其中几种常见的方法,以及它们的优缺点: 优点: rand crate 是 Rust 中最常用的随机数库,提供了多种随机数生成器和功能。它易于使用,并且具有广泛的社区支持。 缺点: rand crate 生成的随机数是伪随机数,可能不

    2024年02月14日
    浏览(46)
  • 【Linux】随机数的生成

    /dev/random是一个随机数生成器设备文件,用于生成高质量的随机数。它通过收集系统上的环境噪声(例如硬件噪声,磁盘活动等)来产生随机数。由于它只在系统上有足够的环境噪声时才能生成随机数,因此/dev/random生成的随机数是高质量的。 但是,/dev/random的主要缺点是,如

    2024年02月11日
    浏览(48)
  • MySQL、Oracle 生成随机ID、随机数、随机字符串

    UUID():是由128位的数字组成的全局唯一标识符。每次都生成一个新的随机数。 它通常以32个十六进制数的形式表示,分为5个部分,以连字符分隔。 UUID的长度是36个字符,包括32个十六进制数字和4个连字符。 UUID的标准格式是由 8-4-4-4-12 个十六进制数字组成的,其中每个部分的

    2024年01月16日
    浏览(57)
  • mysql 自动生成随机数

    在MySQL中,生成随机数可以使用`RAND()`函数。以下是一些基本用法: 1. **生成0到1之间的随机浮点数**:    ```sql    SELECT RAND();    ``` 2. **生成指定范围内的随机整数**(例如,生成1到100之间的随机整数):    ```sql    SELECT FLOOR(RAND() * 100) + 1;    ```    这里,`RAND()`生成0到

    2024年01月22日
    浏览(53)
  • 如何使用Verilog生成随机数

    输入:时钟信号,复位信号,重新加载信号,种子 输出:随机数 输入一个种子32位,输出16位随机数;选取时钟,复位,重新加载种子。 // 使用32个逻辑单元用于D触发器/加法器和8个DSP块用于32x18=32位乘法 module c_rand (   input clk,         // 时钟输入   input rst,        

    2024年02月03日
    浏览(40)
  • Python随机生成1到100随机数的常用方法!

    编写程序时,我们经常需要用到随机数,而且随机数在很多场景下都很有用,比如游戏、密码生成等等,那么Python如何随机生成1到100的随机数?以下是常用方法介绍。 1、使用random模块 Python中的random模块提供了生成随机数的函数。其中,randint()函数可以生成指定范围内的随机

    2024年04月15日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包